简体   繁体   中英

Do I need to unsubscribe from an Angular Observable?

It's surprisingly hard to get a straight answer on if and when you should unsubscribe from an Angular Observable.

I have the following scenario:

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

There are a few solutions I see:

  1. Don't store the subscription as a variable, does this mean I don't have to unsubscribe?

     this.service.makeHTTPCall(stuff).subscribe(x => { //do something });
  2. Store the subscription as a variable and unsubscribe in ngOnDestroy

    ngOnDestroy() { if (this.subscription) { this.subscription.unsubscribe(); } }
  3. Do nothing, Angular sorts all of the unsubscribe stuff out for you

I know there are third party libraries like ng-take-until-destroy , but assuming we don't have any third party libraries which is the advised method for unsubscribing?

You don't need to unsubscribe manually HTTP Observable and Router observable. Other than these two, any subject, or observable you create you have manually unsubscribe using one way you already mentioned, another way can be using async operator.. The async operator automatically unsubscribes for you, also another way you can use takeUntil operator

From https://stackoverflow.com/a/41177163/2987066

TLDR:

For this question there are (2) kinds of Observables - finite value and infinite value.

http Observables produce finite (1) values and something like a DOM event listener Observables produce infinite values.

If you manually call subscribe (not using async pipe), then unsubscribe from infinite Observables.

Don't worry about finite ones, RxJs will take care of them.

You don't need to unsubscribe manually HTTP Observable and Router observable. For all others subscribers the best practice is to create an subject destroy$ and then take all the subscribers until destroy$ is active using the rxjs pipe takeUntil(). In the ngOnDestroy than you emit true in the destroy$ subject and unsubscribe from it. All the others subscribers will stop together. Angular do not sorts all of the unsubscribe stuff out for you, you should do it yourself. It can provide to many hard debuggable bugs to leave gost subscribers after component destroy. Below is the example code:

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

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

ngOnDestroy() {
  this.destroy$.next(true);
  this.destroy$.unsubscribe();
}

In html template the async pipe trigger the unsubscribe automatically, so when you use it you can not bother about it.

For some cold observables, you don't need to manually unsubscribe because they will emit once and then complete immediately after. The http service is an example of such an observable.

That being said, if if you don't know whether an observable will emit once and complete immediately , then you should always do proper cleanup.

Personally, I prefer using the take(1) operator, which will take the first response and then unsubscribe itself:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM