What is the difference between Observable and a Subject in rxjs?

I was going through this blog and reading about Observables and couldn't figure out the difference between the Observable and a Subject.


In stream programming there are two main interfaces: Observable and Observer.

Observable is for the consumer, it can be transformed and subscribed:

observable.map(x => ...).filter(x => ...).subscribe(x => ...)

Observer is the interface which is used to feed an observable source:

observer.next(newItem)

We can create new Observable with an Observer:

var observable = Observable.create(observer => { 
    observer.next('first'); 
    observer.next('second'); 
    ... 
});
observable.map(x => ...).filter(x => ...).subscribe(x => ...)

Or, we can use a Subject which implements both the Observable and the Observer interfaces:

var source = new Subject();
source.map(x => ...).filter(x => ...).subscribe(x => ...)
source.next('first')
source.next('second')

Observables are unicast by design and Subjects are multicast by design.

if you look at the below example - each subscription receives the different values as observables developed as unicast by design.

import {Observable} from 'rxjs';

let obs = Observable.create(observer=>{
   observer.next(Math.random());
})

obs.subscribe(res=>{
  console.log('subscription a :', res); //subscription a :0.2859800202682865
});

obs.subscribe(res=>{
  console.log('subscription b :', res); //subscription b :0.694302021731573
});

this could be weird if you are expecting the same values on both the subscription.

we can overcome this issue using Subjects. Subjects is similar to event-emitter and it does not invoke for each subscription. consider the below example.

import {Subject} from 'rxjs';

let obs = new Subject();

obs.subscribe(res=>{
  console.log('subscription a :', res); // subscription a : 0.91767565496093
});

obs.subscribe(res=>{
  console.log('subscription b :', res);// subscription b : 0.91767565496093
});

obs.next(Math.random());

both the subscription are got the same output value!.