我需要取消订阅 Angular Observable 吗?

很难在 if and when 上得到一个直接的答案,你应该取消订阅 Angular Observable。

我有以下情况:

this.subscription = this.service.makeHTTPCall(stuff).subscribe(x => {
//do something
});

我看到了一些解决方案:

1.不要将订阅存储为变量,是不是就不用退订了?

 ```
this.service.makeHTTPCall(stuff).subscribe(x => {
//do something
});

``` 

2.将订阅存储为变量并在ngOnDestroy中取消订阅

 ```
ngOnDestroy() {
if (this.subscription) { this.subscription.unsubscribe(); }
}

``` 
  1. 什么都不做,Angular 会为你整理所有退订的东西

我知道有像 ng-take-until-destroy 这样的第三方库,但假设我们没有任何第三方库,这是建议的退订方法?

stack overflow Do I need to unsubscribe from an Angular Observable?
原文答案
author avatar

接受的答案

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

来自 https://stackoverflow.com/a/41177163/2987066

TLDR:

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

http Observables 产生有限 (1) 值,而类似于 DOM 事件侦听器 Observables 产生无限值。

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

不要担心有限的,RxJs 会照顾他们的。


答案:

作者头像

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

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

作者头像

对于一些冷的 observable,你不需要手动取消订阅,因为它们会发出一次,然后立即完成。 http 服务就是这种 observable 的一个例子。

话虽如此,如果 if you don't know whether an observable will emit once and complete immediately ,那么您应该始终进行适当的清理。

就我个人而言,我更喜欢使用 take(1) 运算符,它将接受第一个响应,然后自行取消订阅:

someObs.pipe(take(1)).subscribe(...)