subjects in rxjs

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 next, error, and 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();
subject.subscribe(observer1);
subject.subscribe(observer2);
tick$.subscribe(subject);

The example above is “multicasting” the observable tick$ to two observers: observer1 and observer2. This is actually what almost all multicasting operators in RxJS do internally. For example publish, publishReplay, multicast, 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 complete or 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

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s