![](/img/trans.png)
[英]Angular observables - Do I need unsubscribe if no subscription?
[英]With RxJs in Angular do I need to only complete the Observables created in the component?
基本上,我還是不太確定Angular組件中的反應式代碼是否清理。 以下規則正確且充分嗎?
我的反應式組件規則:
我不確定最后一點。
這是我根據這些規則重構的真實組件的完整示例,有人可以看到內存泄漏是否存在危險嗎? 所有公共的$ observable都是通過模板中的異步管道進行訂閱的,因此我確定訂閱已得到處理。 使用new創建的主題將被手動清理,因此應該可以。 我擔心的部分是Observable.combineLatest(...)可觀察對象。
import { ChangeDetectionStrategy, Component, Input, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { DeliveryPointId } from 'app/bso';
import { BookmarkService } from 'app/general';
import { EAccess, EPermission, ReduxGetters, ReduxService } from 'app/redux';
import * as routing from 'app/routing';
import { BehaviorSubject, Observable } from 'app/rx';
@Component({
selector: 'app-last-opened-workitems-widget',
templateUrl: './last-opened-workitems-widget.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LastOpenedWorkitemsWidgetComponent implements OnDestroy {
private readonly showPartners$ = new BehaviorSubject(true);
private readonly showServices$ = new BehaviorSubject(true);
private readonly showTens$ = new BehaviorSubject(true);
private readonly showWorklist$ = new BehaviorSubject(true);
@Input() set showItems(val: boolean) { this.showWorklist$.next(!!val); }
@Input() set showPartners(val: boolean) { this.showPartners$.next(!!val); }
@Input() set showProcesses(val: boolean) { this.showServices$.next(!!val); }
@Input() set showTens(val: boolean) { this.showTens$.next(!!val); }
constructor(
private readonly redux: ReduxService,
private readonly bookmarks: BookmarkService,
private readonly router: Router,
) { }
canPartners$ = this.redux.watch(ReduxGetters.userAccess).map(access => access[EPermission.Partner] >= EAccess.Read);
canServices$ = this.redux.watch(ReduxGetters.userAccess).map(access => access[EPermission.Services] >= EAccess.Read);
canTens$ = this.redux.watch(ReduxGetters.userAccess).map(access => access[EPermission.Tens] >= EAccess.Read);
canWorklist$ = this.redux.watch(ReduxGetters.userAccess).map(access => access[EPermission.Worklist] >= EAccess.Read);
lastItems$ = this.bookmarks.onLastOpenedWorkitems.map(ii => [...ii].reverse());
lastPartners$ = this.bookmarks.onLastOpenedPartners.map(ii => [...ii].reverse());
lastProcesses$ = this.bookmarks.onLastOpenedProcesses.map(ii => [...ii].reverse());
lastTens$ = this.bookmarks.onLastOpenedTens.map(ii => [...ii].reverse());
hasContentPartners$ = Observable
.combineLatest(
this.showPartners$.distinctUntilChanged(),
this.canPartners$,
this.lastPartners$.map(ii => ii.length > 0))
.map(oks => oks.every(ii => ii));
hasContentServices$ = Observable
.combineLatest(
this.showServices$.distinctUntilChanged(),
this.canServices$,
this.lastProcesses$.map(ii => ii.length > 0))
.map(oks => oks.every(ii => ii));
hasContentTens$ = Observable
.combineLatest(
this.showTens$.distinctUntilChanged(),
this.canTens$,
this.lastTens$.map(ii => ii.length > 0))
.map(oks => oks.every(ii => ii));
hasContentWorklist$ = Observable
.combineLatest(
this.showWorklist$.distinctUntilChanged(),
this.canWorklist$,
this.lastItems$.map(ii => ii.length > 0))
.map(oks => oks.every(ii => ii));
hasContent$ = Observable
.combineLatest(this.hasContentPartners$, this.hasContentServices$, this.hasContentTens$, this.hasContentWorklist$)
.map(oks => oks.some(ii => ii));
ngOnDestroy() {
[this.showPartners$, this.showServices$, this.showTens$, this.showWorklist$].forEach(ii => ii.complete());
}
gotoPartner = (id: string) => routing.gotoPartnerItem(this.router, id);
gotoProcess = (id: number) => routing.gotoProcess(this.router, id);
gotoTensItem = (id: DeliveryPointId) => routing.gotoTensItem(this.router, id);
gotoWorkitem = (id: number) => routing.gotoWorkitem(this.router, id);
}
您需要取消訂閱每個訂閱,例如在ngOnDestroy()
方法中。
或者您可以使用諸如takeUntil()
, take()
, first()
等運算符來“限制”可觀察對象。
上面的規則也適用於combineLatest
。
不必擔心AsyncPipe
創建的訂閱,因為AsyncPipe
本身負責取消訂閱其自己的訂閱。
RxJS負責人Ben Lesh的文章對此主題有很好的閱讀。
好的,我實際上只是使用.finally(...)加上所有中間Observable的日志記錄對其進行了測試,並且在銷毀組件時可以正確觸發它。
因此,我宣布上述規則正確無誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.