Reactive Extensions for Javascript – Observable vs ConnectableObservable

For those of you who are famil­iar with Reac­tive Exten­sions you should know all about observ­ables already, but did you know that there’s anoth­er kind of observ­able sequence – Rx.ConnectableObservable.

The dif­fer­ence between the two types of observ­able sequences is well explained here, in short, a con­nectable observ­able sequence allows you to share the same source sequence of val­ues with mul­ti­ple sub­scribers whilst the nor­mal observ­able sequence gives each sub­scriber its own sequence of val­ues. Whilst in most cas­es this dif­fer­ence doesn’t have any prac­ti­cal impacts as each sub­scribers are giv­en the same val­ues in the same order, how­ev­er, con­sid­er this observ­able sequence of ran­dom num­bers between 0 and 1000:

   1: var maxNumber = 1000;

   2: var observableSource = Rx.Observable.GenerateWithTime(

   3:     Math.random(),                                      // initial state

   4:     function (x) { return true; },                      // condition

   5:     function (x) { return Math.random(); },             // iterator     

   6:     function (x) { return parseInt(x * maxNumber); },   // select

   7:     function (x) { return 1000 });                      // interval

As you can see, each time the iter­a­tor is invoked it’ll gen­er­ate a dif­fer­ent val­ue, hence sub­scribers will receive a dif­fer­ent val­ue each time (see demo below):

   1: // first subscriber

   2: observableSource.Subscribe(function (n) {

   3:     sub1Span.html(n);

   4: });

   5:  

   6: // second subscriber

   7: observableSource.Subscribe(function (n) {

   8:     sub2Span.html(n);

   9: });

Instead, if you want to ensure that all the sub­scribers receive the same val­ues, your best bet is to ‘pub­lish’ the source:

   1: // create a connectable observable from the source

   2: var connectableObservable = observableSource.Publish();

which returns you a con­nectable observ­able that you can then attach sub­scribers to:

   1: // connected subscriber 1

   2: connectableObservable.Subscribe(function (n) {

   3:     connSub1Span.html(n);

   4: });

   5:  

   6: // connected subscriber 2

   7: connectableObservable.Subscribe(function (n) {

   8:     connSub2Span.html(n);

   9: });

and once you ‘con­nect’ to the under­ly­ing source, the sub­scribers will start receiv­ing val­ues from the stream:

   1: connectableObservable.Connect();

Demo