[英]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.