angular - 为什么在 Angular takeuntil ngUnsubscribe 的 'next' 之前有一个 'complete'?

标签 angular rxjs

有大量关于使用“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(),那么它会导致无法订阅。

2) takeUntil 就是这样设计的。它只对 next 通知使用react。如果您不想同时调用 next()complete(),您可以使用 defaultIfEmpty() 运算符:

this.router.routerUrl$.pipe(
  takeUntil(this.ngUnsubscribe.pipe(
    defaultIfEmpty(null),
  ))
).subscribe(...);

然后你可以调用 this.ngUnsubscribe.complete() 它也会触发 takeUntil

实际上,在您的示例中,如果您调用 next(),您甚至不需要调用 complete(),因为下一个通知将使链进行处理。

关于angular - 为什么在 Angular takeuntil ngUnsubscribe 的 'next' 之前有一个 'complete'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54174424/

相关文章:

angular - ng-select 中的 ng-dropdown-panel - 即使使用了appendTo ="body",如何保留其自定义样式

javascript - 在js文件中加载html文件

angular - 是否可以在没有值的情况下向 Angular 宿主元素添加属性

rxjs - 如何检测变量的变化?

javascript - RxJS ReplaySubject 观察者长度在下一个之后不会增加

使用 ngFor 可观察 Angular

angular - 从 Promise 内部返回已解决的 Observable

javascript - 防止使用 iOS 返回按钮提交表单

javascript - Http get后访问组件中的数组

rxjs - 切换到新的可观察值,并使用先前可观察值的最新值作为输入