20

I was reading through the RxJS docs and want to make sure I'm understanding the difference between Subscriber.unsubscribe() and Subscriber.complete().

Let's say I have an observable with two subscribers, subscriber1 and subscriber2. If subscriber1 calls unsubscribe on their subscription, it will no longer receive notifications from the observable but subscriber2 will continue to receive them.

The docs for .complete():

The Observer callback to receive a valueless notification of type complete from the Observable. Notifies the Observer that the Observable has finished sending push-based notifications.

Does this mean that in the same scenario above, subscriber1 could call complete and it would end the observable and stop the stream for both subscriber1 and subscriber2?

BrentShanahan
  • 681
  • 1
  • 7
  • 17
  • 2
    You seem to be confusing Subscriber and Subscription APIs, please clarify. – jonrsharpe Feb 13 '18 at 16:35
  • Ya you are correct now that I looked at the docs again. I think this is what threw me off in regards to Subscriber: "Observers get converted to a Subscriber, in order to provide Subscription-like capabilities such as unsubscribe." When what is returned from Observable.subscribe is a Subscription and not a Subscriber. – BrentShanahan Feb 13 '18 at 16:55

2 Answers2

18

Subscribers don't call complete(). You can call complete() on a Subject or more typically it's called for you "indirectly" using operators such as take(), takeWhile(), ...

For example:

const s = new Subject();
const subscriber1 = s.subscribe(...);
const subscriber2 = s.subscribe(...);
s.complete(); // both subscribers will receive the complete notification

// or with `take(1)` operator it'll call `complete()` for you
const subscriber1 = s.take(1).subscribe(...);
const subscriber2 = s.take(1).subscribe(...);
s.next(42); // both subscribers will receive the complete notification

Note that calling complete() on a Subject changes its inner state and there's no way to make it non-complete again while just unsubscribing a subscriber has no effect on the Subject.

A little similar question: Observable Finally on Subscribe

martin
  • 93,354
  • 25
  • 191
  • 226
  • 1
    Subject provides both an unsubscribe and a complete so it looks as though that is what I was looking at in my code and assumed it was a Subscriber based on the docs, oops. Digging into the RxJS code it looks as though Subject.complete() will call complete on each of it's observers where as unsubscribe just removes all observers from the subject by setting observers to null. Interesting, thanks. – BrentShanahan Feb 13 '18 at 17:35
9

From my experience with the API, the idea is that: you don't call the Observable, the Observable calls you. You are able to trigger things if you create a Subject and next/complete the Subject though.

That's why you will see some examples that have a "private" Subject as a class member, but the publicly exposed item is an Observable. The expectation is that you will subscribe to the Observable and the top level class will dispatch values through the Subject with next() and error(). The only way to complete the Observable/Subject is to complete() the Subject.

Additionally, Subscriber does not have an unsubscribe() method, a Subscription does.

zero298
  • 25,467
  • 10
  • 75
  • 100