我需要取消订阅 Angular Observable 吗?

use*_*er1 5 rxjs typescript angular rxjs-observables

令人惊讶的是,很难得到关于是否以及何时应该取消订阅 Angular Observable 的直接答案。

我有以下场景:

this.subscription = this.service.makeHTTPCall(stuff).subscribe(x => {
//do something
});
Run Code Online (Sandbox Code Playgroud)

我看到的解决方案有以下几种:

  1. 不要将订阅存储为变量,这是否意味着我不必取消订阅?

    this.service.makeHTTPCall(stuff).subscribe(x => {
    //do something
    });
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将订阅存储为变量并在 ngOnDestroy 中取消订阅

    ngOnDestroy() {
    if (this.subscription) { this.subscription.unsubscribe(); }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 什么也不做,Angular 会为你整理所有取消订阅的内容

我知道有像 之类的第三方库ng-take-until-destroy,但假设我们没有任何第三方库,这是建议的取消订阅方法吗?

vna*_*iuk 8

您不需要手动取消订阅 HTTP Observable 和 Router observable。对于所有其他订阅者,最佳实践是创建一个主题 onDestroy$,然后使用 rxjs 管道 takeUntil() 获取所有订阅者,直到 onDestroy$ 处于活动状态。在 ngOnDestroy 中,您在 onDestroy$ 主题中发出 true 并取消订阅它。所有其他订阅者将一起停止。Angular 不会为你整理所有取消订阅的内容,你应该自己做。它可以提供许多难以调试的错误,以便在组件销毁后留下 gost 订阅者。下面是示例代码:

onDestroy$: Subject<boolean> = new Subject();

ngOnInit() {
 this.service.someSubscriber.pipe(takeUntil(this.onDestroy$)).subscribe(() => 
{ //do stuff 
})
this.service.someSubscriber2.pipe(takeUntil(this.onDestroy$)).subscribe(() => 
{ //do stuff 
})
this.service.someSubscriber3.pipe(takeUntil(this.onDestroy$)).subscribe(() => 
{ //do stuff 
})
}

ngOnDestroy() {
  this.onDestroy$.next(true);
  this.onDestroy$.unsubscribe();
}
Run Code Online (Sandbox Code Playgroud)

在html模板中,异步管道会自动触发取消订阅,因此当您使用它时您不必担心它。


Joh*_*man 3

您不需要手动取消订阅 HTTP Observable 和 Router observable。除了这两个之外,您创建的任何主题或可观察对象都可以使用您已经提到的一种方式手动取消订阅,另一种方式可以使用运算符。异步运算符会自动为您取消订阅,这也是您可以使用运算符的async另一种方式takeUntil

来自/sf/answers/2882401441/

总而言之:

对于这个问题,有 (2) 种 Observables - 有限值和无限值。

http Observables 产生有限 (1) 个值,而诸如 DOM 事件监听器之类的 Observables 产生无限值。

如果您手动调用 subscribe (不使用异步管道),则取消订阅无限 Observables。

不用担心有限的问题,RxJ 会处理它们。