Be the first user to complete this post

  • 0
Add to List

Difference between Rxjs Subject and Observable

In order to understand the difference between a Subject and an Observable, you need to be aware of two distinct concepts - A data producer - A data consumer An observable, by definition is a data producer. Albeit a special kind that can produce data over time. A Subject on the other hand can act as both - a data producer and a data consumer. This implies two things. 1. A subject can be subscribed to, just like an observable. 2. A subject can subscribe to other observables. That being said, there is one critical difference between a subject and an observable.

All subscribers to a subject share the same execution of the subject. i.e. when a subject produces data, all of its subscribers will receive the same data. This behavior is different from observables, where each subscription causes an independent execution of the observable.
Lets see some examples
var subject = new Rx.Subject();

// Here the subject is acting like a data producer
// because it is being subscribed to
subject.subscribe(v => console.log('consumer A: ' + v));
subject.subscribe(v => console.log('consumer B: ' + v));

// Create a source of the data, which in our case is an observable
var observable = Rx.Observable.from([0, 1]);

// Here the same subject acs as a data consumer because it
// can subscribe to another observable
observable.subscribe(subject);

/* Prints */
// Consumer A: 0
// Consumer B: 0
// Consumer A: 1
// Consumer B: 1
There are a few important things to notice about this example. 1. I had to setup my subscriptions before my subject subscribed to the source. 2. Both the consumers logged the same value for v. The fact that our consumers log the same data implies that the broadcasted data is shared with all the consumers/subscribers. This is unlike observables, where each consumer/subscriber causes the observable function to be re-executed. Lets see another example to clarify this.

Example 1

Vanilla observable, independent execution
var observable = Rx.Observable.create(function(source) {
  source.next(Math.random());
});

observable.subscribe(v => console.log('consumer A: ' + v));
observable.subscribe(v => console.log('consumer B: ' + v));

/* Prints DIFFERENT values for both consumers */
// consumer A: 0.25707833297857885
// consumer B: 0.8304769607422662

Example 2

Observable wrapped in a subject, causing shared execution
var observable = Rx.Observable.create(function(source) {
  source.next(Math.random());
});

var subject = new Rx.Subject();

subject.subscribe(v => console.log('consumer A: ' + v));
subject.subscribe(v => console.log('consumer B: ' + v));

observable.subscribe(subject);

/* Prints SAME values for both consumers */
// consumer A: 0.8495447073368834
// consumer B: 0.8495447073368834

You can also manually broadcast data from a subject to it observers using the next() function as shown below.
var subject = new Rx.Subject();

subject.subscribe(v => console.log('consumer A: ' + v));

subject.next('hello world');

/* Prints */
// consumer A: hello world

I hope this post effectively takes you a step closer towards getting comfortable with using Subjects and Observables in your projects with confidence.



Also Read:

  1. The difference between Rxjs combineLatest and withLatestFrom
  2. The difference between switchMap and flatMap or mergeMap
  3. Getting started with Rxjs and streams
  4. Rxjs Observable publish refcount vs share