![](/img/trans.png)
[英]With RxJs in Angular do I need to only complete the Observables created in the component?
[英]Which observables do Angular complete automatically?
Angular產生的哪些observables也由Angular完成?
例如:
HttpClient
在請求完成時完成所有 observablesRouter
的 observables(parammap、queryparammap 等)會自動完成。Angular 中的哪些其他可觀察值Angular會在什么情況下自動為您完成?
當路由改變時,來自路由器的 observables [...] 會自動完成。
我不會說這是真的。 當路由更改時,該視圖被銷毀,並且由於每個ActivatedRoute
都與一個路由相關聯(因此與一個路由組件相關聯),當該組件被銷毀時,其中的所有內容都將被銷毀,以及對屬於該組件的源的任何訂閱(例如ActivatedRoute.params
)。 至少這是我注意到的,但是當路由更改時,它肯定不會發出完整的通知。
這同樣適用於@ViewChildren
。 由於它會從當前組件的視圖中查詢元素,當組件被銷毀時,該源( @ViewChildren.changes
)也將被清空,因此無需手動取消訂閱。
valueChanges
或statusChanges
相同(假設表單控件是在該組件中創建的)。
例如,當您擁有全局服務時,可能會發生 Memory 泄漏。 因為它是全局的,所以它只保留對訂閱者的引用,訂閱者可以來自多個地方。 但是由於全局服務的存在不依賴於組件是否被銷毀,所以由該組件讓服務知道它不再對接收值感興趣。
守衛會發生一些非常有趣的事情。
當使用canLoad
守衛時,如果你返回一個 observable,你必須確保你的 observable 完成(例如通過添加take(1)
)。 這很重要,因為 Angular不會自動為您處理:
sbj = new BehaviorSubject(true)
canLoad (route: Route, segments: UrlSegment[]) {
// Although it's returning `true`, it never completes
return this.sbj;
}
從它的實現我們可以看出原因:
// Observable that will emit each `canLoad` individually
const obs = from(canLoad).pipe(map((injectionToken: any) => {
const guard = moduleInjector.get(injectionToken);
let guardVal;
if (isCanLoad(guard)) {
guardVal = guard.canLoad(route, segments);
} /* ... */
return wrapIntoObservable(guardVal);
}));
return obs.pipe(
// `concatAll` === `mergeMap(obs => obs, 1)`
// `concatAll` requires an observable to **complete** in order to subscribe to the next one
concatAll(),
/* ... */
every(result => result === true),
);
另一方面,例如使用canActivate
時,情況就不同了。 這一次,Angular 將自動取第一個值然后完成,所以這應該工作:
sbj = new BehaviorSubject(true);
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.sbj;
}
如實施中所見:
const canActivateObservables = canActivate.map((c: any) => {
return defer(() => {
const guard = getToken(c, futureARS, moduleInjector);
let observable;
if (isCanActivate(guard)) {
observable = wrapIntoObservable(guard.canActivate(futureARS, futureRSS));
} /* ... */
// Only get the first emitted value and then complete
return observable.pipe(first());
});
});
return of(canActivateObservables).pipe(prioritizedGuardValue());
異步 pipe 訂閱 Observable 或 Promise 並返回它發出的最新值。 當發出新值時,異步 pipe 標記要檢查更改的組件。 當組件被銷毀時,異步 pipe 會自動取消訂閱以避免潛在的 memory 泄漏。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.