![](/img/trans.png)
[英]Angular Observable destroy with takeUntil: What happens when .next() is missing in ngOnDestroy
[英]Why a 'next' before 'complete' of Angular takeuntil ngUnsubscribe?
有大量關於使用“takeUntil”運算符取消訂閱流的信息,如下所示:
... export class CategoryOptionInputComponent constructor(private svc: MyService, protected router: RouterService) { ... this.router.routerUrl$.pipe(takeUntil(this.ngUnsubscribe)).subscribe(s => { const param1 = s.state.featureId; this.svc.InitFromApi(param1); }); ... } ngOnDestroy() { this.ngUnsubscribe.next();//<-- This line is confusing this.ngUnsubscribe.complete(); } private readonly ngUnsubscribe = new Subject(); }
如上代碼所示,我們需要在解析的路由器數據上從API加載數據,並在新的路由器數據到達時繼續加載新數據,直到組件被銷毀。
當用戶導航到不同的路線時,預計該組件將在沒有最后一次點擊 API 的情況下被銷毀。 但是,它的行為並不像預期的那樣。 即使組件即將被銷毀,也會調用 API。
我的問題是:
(1) 如何防止組件在死之前命中API?
(2) 為什么不只是 complete() 流,為什么在 complete() 之前調用 next() (參見上面的代碼)?
先謝謝了。
1) 如果您希望 API 調用可取消,則它需要成為可觀察鏈的一部分。 當調用在subscribe
內部執行時,無法取消它,因此您必須為此使用運算符,例如mergeMap
或concatMap
。
this.router.routerUrl$.pipe(
takeUntil(this.ngUnsubscribe),
concatMap(s => {
const param1 = s.state.featureId;
return this.svc.InitFromApi(param1);
})
).subscribe();
然而,這期望this.svc.InitFromApi()
返回一個 Observable 或一個 Promise。 如果您在InitFromApi()
內訂閱或在 Promise 上使用then()
那么它會導致InitFromApi()
訂閱。
2) 這就是takeUntil
的設計方式。 它只對next
通知做出反應。 如果您不想同時調用next()
和complete()
您可以使用defaultIfEmpty()
運算符:
this.router.routerUrl$.pipe(
takeUntil(this.ngUnsubscribe.pipe(
defaultIfEmpty(null),
))
).subscribe(...);
然后你可以只調用this.ngUnsubscribe.complete()
它也會觸發takeUntil
。
實際上,在您的示例中,如果您調用next()
,您甚至不需要調用complete()
,因為下一個通知將使鏈進行處理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.