繁体   English   中英

为什么在 Angular takeuntil ngUnsubscribe 的“完成”之前有一个“下一步”?

[英]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内部执行时,无法取消它,因此您必须为此使用运算符,例如mergeMapconcatMap

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM