Reactive Extensions for Javascript – Multiple observers for multiple observables

One of the great things about the Reactive Extensions for Javascript is that you can easily create a many-to-many relationship between observable sequences of values and observers who handles the arrival of new values.

You should have a read of these couple of posts first:

To take it a step further from the brief code snippets shown in the blog posts by Matthew Podwysocki above, here’s a quick demo on how you can create multiple observable sequences of values and have multiple observers observe them.

So first, a simple set of HTML to create a couple of spans:

   1: <body>

   2:     <div id="wrapper">

   3:         <span id="message" class="block"></span>

   4:         <span id="error" class="block"></span>

   5:         <span id="complete" class="block"></span>

   6:  

   7:         <span id="message-2" class="block"></span>

   8:     </div>

   9: </body>

And the Javascript:

   1: <script type="text/javascript" src="js/jquery/jquery-1.4.4.min.js"></script>

   2: <script type="text/javascript" src="js/rxjs/rx.js"></script>

   3: <script type="text/javascript" src="js/rxjs/rx.jQuery.js"></script>

   4:  

   5: <script type="text/javascript">

   6:     $(function () {

   7:         var wrapperElement = $("#wrapper"),

   8:             messageElement = $("#message"),

   9:             messageElement2 = $("#message-2"),

  10:             errorElement = $("#error"),

  11:             completeEelement = $("#complete");

  12:  

  13:         /********** 1ST OBSERVER (EXPLICIT) ************/

  14:         var observer = Rx.Observer.Create(

  15:             function (next) { // when next value is fired

  16:                 messageElement.html("Next: " + next);

  17:             },

  18:             function (err) { // on error

  19:                 errorElement.html("Error: " + err);

  20:             },

  21:             function () { // on complete

  22:                 completeEelement.html("Complete!");

  23:             });

  24:  

  25:         // an observable that starts from 0 and increments by 1 per second

  26:         var counter = Rx.Observable.GenerateWithTime(

  27:             0,                                  // initial state

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

  29:             function (x) { return x + 1; },     // iterator

  30:             function (x) { return x },          // select

  31:             function (x) { return x === 0 ? 0 : 1000 }); // time (1s) between each value

  32:  

  33:         // an observable sequence which just throws an exception

  34:         var except = Rx.Observable.Throw("FAIL!");

  35:  

  36:         // an observable sequence which completes straight away

  37:         var complete = Rx.Observable.Return();

  38:  

  39:         // get reference to the disposable objects to unsubscribe later

  40:         var counterSub = counter.Subscribe(observer);

  41:         var exceptSub = except.Subscribe(observer);

  42:         var completeSub = complete.Subscribe(observer);

  43:  

  44:         /********** 2ND OBSERVER (IMPLICIT) ************/

  45:         var counterSub2 = counter.Subscribe(function (next) {

  46:             messageElement2.html(next);

  47:         });

  48:  

  49:         // unsubscribe the first observer's counter subscription after 10 seconds

  50:         setTimeout(function () { counterSub.Dispose() }, 10000);

  51:     });

  52: </script>

The key things to note here are the two ways you can create an observer, either explicitly using the Rx.Observer.Create function or creating one dynamically using one of the overloaded Subscribe functions on an observable sequence.

When you call Subscribe on an observable, you get back a disposable object which can then be used to unsubscribe an observer from an ongoing observable sequence (see line 50 in the code above and the demo below).

Demo