[英]RXJS - Angular - unsubscribe from Subjects
As described in this thread , 'official' solution to unsubscribe from Observables in Angular 5+ in general is using takeUntil. 如本主题所述 ,在Angular 5+中取消订阅Observables的“官方”解决方案通常是使用takeUntil。 So far, so good.
到现在为止还挺好。 My question is, does this also apply if the Observable I am subscribed to is actually a Subject?
我的问题是,如果我订阅的Observable实际上是一个主题,这是否也适用?
Once you call .subscribe()
on anything (Subjects too), something needs to make sure the subscription gets unsubscribed. 一旦你在任何事情上调用
.subscribe()
(主题也是如此),需要确保订阅被取消订阅。
Dealing with finite Observables : If you subscribe to a finite observable (meaning an observable that has a finite/limited sequence), the last message will send an end signal and the subscription will be canceled automatically. 处理有限Observables :如果您订阅了有限可观察量(意味着具有有限/有限序列的可观察量),则最后一条消息将发送结束信号,并且订阅将自动取消。 Examples of this are:
这方面的例子是:
Observable.of(100)
Observable.from([1,2,3,4])
Examples of in finite observables are: 在有限观察量的例子是:
Observable.fromEvent(document, 'click')
Observable.timer(1000)
Calling/piping .first()
, .take(number)
or .takeWhile(condition that will evaluate to false at some point)
or takeUntil(observable that emits a value)
on an observable will all turn an otherwise infinite observable into a finite one. 呼叫/管道
.first()
.take(number)
或.takeWhile(condition that will evaluate to false at some point)
或takeUntil(observable that emits a value)
上可观察到的将全部变为一个无限否则可观察到有限一个。
Stop calling .subscribe() : Another popular method of not having to unsubscribe is by not subscribing in the first place. 停止调用.subscribe() :另一种不必取消订阅的流行方法是首先不订阅。 This might sound stupid, since when would you want an observable that you do not subscribe to?
这可能听起来很愚蠢,因为你什么时候想要一个你不订阅的观察者? Well if you only need to pass some data to your view/html template, piping that observable into the async pipe will pass the unsubscribing issue to the async pipe itself.
好吧,如果您只需要将一些数据传递给您的view / html模板,那么将observable传递到异步管道中会将取消订阅问题传递给异步管道本身。
Typical examples in the html template: 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>
Manually unsubscribing : Lastly, you can choose to keep references to all subscriptions. 手动取消订阅 :最后,您可以选择保留对所有订阅的引用。 You don't have to keep a variable pointing to each subscription, it's easier to just use a single Subscription object to keep track of all the subscriptions, and then unsubscribe to all of them at once.
您不必保留指向每个订阅的变量,只需使用单个Subscription对象来跟踪所有订阅,然后立即取消订阅所有订阅。 Here is an example:
这是一个例子:
const subscriptions = new Subscription();
subscriptions.add(observable1$.subscribe());
subscriptions.add(observable2$.subscribe());
subscriptions.unsubscribe();
Quick summerize , how to handle unsubscriptions, any of the below methods: 快速总结 ,如何处理取消订阅,以下任何方法:
.takeUntil(this.destroyed$)
and do this.destroyed$.emit()
in ngOnDestroy()
). .takeUntil(this.destroyed$)
并在this.destroyed$.emit()
中执行this.destroyed$.emit()
ngOnDestroy()
)。 async
pipe. async
管道传递observable。 .unsubscribe()
in the ngOnDestroy()
method. ngOnDestroy()
方法中调用.unsubscribe()
。 Personally i tend to only use one of the two first methods. 我个人倾向于只使用两种方法中的一种。
I have something to add. 我有一些要补充的东西。
Subject
stores the subscribers internally ( Observable
does too). Subject
在内部存储订阅者( Observable
也是如此)。 If the Subject
is part of your component (created inside, stored as property or in a closure) the subject and it's subscriptions are garbage collected with the component itself. 如果
Subject
是组件的一部分(在内部创建,存储为属性或在闭包中),则主题及其订阅将与组件本身一起进行垃圾收集。
But this is a special case and one should be very careful with it: everything must be contained in the component. 但这是一个特例,应该非常小心:一切都必须包含在组件中。
It is eg safe to not unsubscribe from a FormControl.valueChanges
observable if it is used in the component only. 这是如安全不是来自退订
FormControl.valueChanges
如果仅在组件中使用可观察到的。
But to be on the safe side, and don't want to think about it, just use takeUntil
. 但为了安全起见,并且不想考虑它,只需使用
takeUntil
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.