正如this thread所述,'官方'解决方案是取消订阅Angular 5+中的Observable一般使用takeUntil。到现在为止还挺好。我的问题是,如果我订阅的Observable实际上是一个主题,这也适用吗?
答案 0 :(得分:7)
一旦你在任何事情上调用.subscribe()
(主题也是如此),需要确保订阅被取消订阅。
处理有限的Observables : 如果您订阅了有限可观察量(意味着具有有限/有限序列的可观察量),则最后一条消息将发送结束信号,并且订阅将自动取消。 例如:
Observable.of(100)
Observable.from([1,2,3,4])
in 有限可观察量的例子是:
Observable.fromEvent(document, 'click')
Observable.timer(1000)
在一个可观察者上呼叫/管道.first()
,.take(number)
或.takeWhile(condition that will evaluate to false at some point)
或takeUntil(observable that emits a value)
都会将无限的可观察量转变为有限的观察者。
停止调用.subscribe(): 另一种不必取消订阅的流行方法是首先不订阅。这可能听起来很愚蠢,因为你什么时候想要一个你不订阅的观察者?好吧,如果您只需要将一些数据传递给您的view / html模板,那么将observable传递到异步管道中会将取消订阅问题传递给异步管道本身。
html模板中的典型示例:
<h1>Editing {{ infiniteObservable$ | async }}<h1>
<li *ngFor="let user of userObservable$ | async as users; index as i; first as isFirst">
{{i}}/{{users.length}}. {{user}} <span *ngIf="isFirst">default</span>
</li>
手动取消订阅:最后,您可以选择保留对所有订阅的引用。您不必保留指向每个订阅的变量,只需使用单个订阅对象来跟踪所有订阅,然后立即取消订阅所有订阅。 这是一个例子:
const subscriptions = new Subscription();
subscriptions.add(observable1$.subscribe());
subscriptions.add(observable2$.subscribe());
subscriptions.unsubscribe();
快速摘要,如何处理取消订阅,以下任何一种方法:
.takeUntil(this.destroyed$)
中使用this.destroyed$.emit()
和ngOnDestroy()
)。async
管道传递observable。.unsubscribe()
方法致电ngOnDestroy()
。我个人倾向于只使用前两种方法中的一种。
答案 1 :(得分:0)
我要添加一些内容。 Subject
在内部存储订户(Observable
也在内部)。如果Subject
是组件的一部分(在内部创建,存储为属性或在闭包中),则主题及其预订将随组件本身一起被垃圾回收。
但这是一种特殊情况,应该非常小心:所有内容都必须包含在组件中。
例如如果仅在组件中使用,则可以不取消订阅FormControl.valueChanges
。
但是为了安全起见,不想考虑它,只需使用takeUntil
。