简体   繁体   中英

Why do we need to implement unsubscribe in rxjs observable?

Do we need to return our own teardown logic or unsubscribe method inside an observable object?

const observable = new Observable(function subscribe(subscriber) {
  // Keep track of the interval resource
  const intervalId = setInterval(() => {
    subscriber.next('hi');
  }, 1000);

  // Provide a way of canceling and disposing the interval resource
  return function unsubscribe() {
    clearInterval(intervalId);
  };
});

Cause even without the line:

  return function unsubscribe() {
    clearInterval(intervalId);
  };

observable.unsubscribe() is working.

So what's the difference. Why do we need that?

UPDATE Even without returning a custom unsubscribe mmethod the below interval clears automatically when I do an unsbuscribe.

   this.myobs$ = new Observable((subscriber) => {
      let count = 0;
      setInterval(() => {
        subscriber.next(count++);
      }, 1000);
    });

this.myobs$.unsubscribe()

In the following code we are not returning an unsubscribe method:

const hello = Observable.create(function(observer) {
  observer.next('Hello');
  observer.next('World');
  observer.complete();
});

While in here we are returning:

const evenNumbers = Observable.create(function(observer) {
  let value = 0;
  const interval = setInterval(() => {
    if (value % 2 === 0) {
      observer.next(value);
    }
    value++;
  }, 1000);

  return () => clearInterval(interval);
});

But the truth is that even without clear interval my subscription cancels out when I unsubscribe()

Because it's a good practice. It avoids memory leaks. Imagine an app with a service emitting data to many listeners, if you do not unsubscribe in an listener, every emission by the observable will cause the app to receive the data which is undesired. The best practice is to subscribe when it's needed and unsub when you don't need to receive anymore.

This is to provide a custom teardown to the Observable logic.

In this case, you are using setInterval which is a browser meth od.So when you unsubscribe without a custom unsubscribbe. The observerle won't know, it need to clear the interval and the interval will still be running even you after you unsubscribe.

Thus need to to tell the observable that when you unsubscribe, go and clearInterval

Observables do not have an unsubscribe method, you need a subscription object to manage your subscription.

const sub = obs$.subscribe(val => { doStuffWithVal(val); });

Your teardown function can use the sub object to unsubscribe with sub.unsubscribe() .

If you don't unsubscribe then you can cause a memory leak if the observable is not garbage collected and your object is still subscribed.

It is good practice to complete observables and unsubscribe from subscriptions when your are finished with them. It is better to have unnecessary teardown than memory leaks.

Because observable doesn't know what needs to be run in order to unlisten to different event,(eg for interval is clearinterval, timeout is clearTimeout, event is removeEventListener etc)

That's why there is a need to provide an unlistening/unsubscribe functions to be executed in order to truely clear things up.

To demonstrate, the code below you should see the console.log() is still executing even after you unsubscribe()

   this.myobs$ = new Observable((subscriber) => {
      let count = 0;
      setInterval(() => {
        // it should continue to run even after unsubscribe
        console.log('interval running')
        subscriber.next(count++);
      }, 1000);
    }).subscribe();

this.myobs$.unsubscribe()

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