RxJS Subjects different take on the GoF Observer Pattern Subjects, but their API duck-types as an Observable. In fact, in RxJS, Subjects even inherit from Observable. The advantage here is that all Subjects then have the same operators and methods available to them as Observables do.
Probably a more important distinction between Subject and Observable is that a Subject has state, it keeps a list of observers. On the other hand, an Observable is really just a function that sets up observation.
While Subjects are Observables, Subjects also implement an Observer interface. That is to say, they have
complete methods. These methods are used to notify their counterparts on observers in the subject’s internal observers list. This means a subject can be used as an observer to subscribe to any observable.
// To "share" the observable tick$ with two observers, // observer1 and observer2, we can pipe all notifications // through a Subject, like so
const tick$ = Observable.interval(1000); const subject = new Subject();
The example above is “multicasting” the observable
tick$ to two observers:
observer2. This is actually what almost all multicasting operators in RxJS do internally. For example
share, etc. Really, this is the primary use case for Subjects in RxJS.
Subjects Are Not Reusable
In RxJS, Subjects cannot be reused. That is to say, when a Subject completes or errors, it can no longer be used. If you try to
next on a Subject that is
closed due to it’s
error method being called, it will silently ignore the notification. If you want the Subject to loudly and angrily error when you next to it after it’s done being useful, you can call
unsubscribedirectly on the subject instance itself.
// The death of a Subject const subject = new Subject();
subject.subscribe(x => console.log(x));
subject.next(1); // 1 subject.next(2); // 2 subject.complete(); subject.next(3); // silently ignored
subject.unsubscribe(); subject.next(4); // Unhandled ObjectUnsubscribedError