Difference between Cold observable and Replay subject?

To elaborate further on the previous answer, I would recommend you to have a look at another SO question which should help make things more clear : Hot and Cold observables : are there 'hot' and 'cold' operators?

Yes, if we talk about a replay(), i.e. without any arguments, the behaviour of a replay and a cold observable look similar. However, they are not the same.

For instance,

cold$ = Rx.Observable.just(1).map(function(){return Math.random();});
coldReplay$ = cold$.replay();
cold$.subscribe(function(x){console.log('cold:' + x);})
cold$.subscribe(function(x){console.log('cold:' + x);})
coldReplay$.subscribe(function(x){console.log('replay:' + x);});
coldReplay$.subscribe(function(x){console.log('replay:' + x);});

will never give you the same values when you subscribe to the replay and when you subscribe directly the cold observable.

Why is that should be clear from the link aforementioned. When you subscribe to a cold observable, you start from the first source down to the subscription. When you replay, you don't restart, the replay has kept in a buffer the values that were emitted, and pass directly immediately those values from the buffer and the new ones.


Once the ReplaySubject subscribes to the source observable, the source begins emitting, and the ReplaySubject becomes a hot observable. From a subscriber standpoint, subscribing the the ReplaySubject it may not be obvious, as it gets all the previously emitted values. But the ReplaySubject only subscribes to the source once, so the only way for the subject to be able to re-emit those source values to later subscribers, is to cache those values.

So the difference would be that when subscribing straight to the source observable, the source re-emits the values for each subscriber, whereas with the ReplaySubject subscribing to the source, the source only emits once, and any subscriber to the subject, gets those cached values.

Consider the following source observable

var source = Rx.Observable.create(function(subscriber) {
  for (var i = 0; i < 2; i++) {
    subscriber.onNext(i);
    console.log("onNext: " + i);
  }
  subscriber.onCompleted();
});

If we subscribe directly to the source, we should see the set of logs twice

source.subscribe(function(value) {});
source.subscribe(function(value) {});
//onNext: 0
//onNext: 1
//onNext: 0
//onNext: 1

With the ReplaySubject, once it subscribes to the source, the source begins emitting, causing the hot subject to begin emitting and caching the values.

var subject = new Rx.ReplaySubject();
source.subscribe(subject);
setTimeout(function() {
  console.log('subscribe subject');
  subject.subscribe(function(value) { console.log('subscriber')});
  subject.subscribe(function(value) { console.log('subscriber')});
}, 100);
//onNext: 0
//onNext: 1
//subscribe subject
//subscriber
//subscriber
//subscriber
//subscriber

Here, you see the source begins emitting once it is subscribed to by the subject. But any subscriptions to the subject, doesn't cause the source to re-emit, as with the previous example where each new subscriber causes the source to re-emit.