How to wrap your brain around Rx and RxJS

When Linq was first announced almost every developer got it. Writing queries over data is our bread and butter. How much easier it is to declare queries, than writing imperative For loops with lots of temporary variables (*shiver*).

But when Rx came around only a couple of academics and a handful of super geeks got it. They said “Rx is the mathematical dual of the IEnumerable, etc, etc…”

This is where the brain wrapping comes in. Most developers are building sequential deterministic machines (or are trying to), using code to glue it all together. With Rx it is all about reactive programming. Instead of calling methods synchronously and waiting for a response, reactive programming is all about events, don’t-ask-but-tell-principle and pub/sub.

The observable

At the basis of Rx and RxJS lies the IObservable and the IObserver. Think about it! IObservable, something that you can observe. Translate that to an event or a happening or even better, turn an event into an Observable and you’re ready to start composing. You’re right, an example…

My examples are in JavaScript. YES, JavaScript, but don’t worry. It is not about browser differences, or JavaScript is better than language X. No, my opinion is that JavaScript is an easy and flexible language and is easy to translate to your language of choice. And Rx  is not .NET  only.

$('#input-control').toObservable("keypress");

// Or...

var observable = $('#input-control').toObservable("keypress");

As you can see I’m using the RxJS jQuery extension, which turns jQuery events into Observables. RxJS also supports these other JavaScript frameworks by adding one of the following extensions.

  • rx.dojo.js
  • rx.google.language.js
  • rx.googlemaps.js
  • rx.html.js
  • rx.jQuery.js
  • rx.microsoft.translator.js
  • rx.mootools.js
  • rx.prototype.js
  • rx.raphael.js
  • rx.virtualearth.js
  • rx.yui3.js

Back to the example. What we have done in the first example is is just like turning data into an IEnumerable, is turining an event into an Observable. Having all your data or events in the same format is The trick to do cool stuff.

Just like IEnumerables in C#, the extensions methods are the Combinators and are providing the actual power of the concept. Enumerables and Observables themselves are pretty boring. They both provide three important things, namely…

  • Next; Give me the next value / Here is the next value
  • Complete; Do you have more? / There is no more
  • Exception; Try, Catch, Finally / I want to inform you about an exception

* The left comment is the proactive way of thinking and on the right the Reactive.

The combinators

If the Combinators are the fun part, let’s talk about them. What are Combinators, how many are there and what do you do with them?

Let’s name a couple of combinators you probably have heard of in the Enumerable camp, namely… Where/Map, Select, Sum, Group By, Join, etc, etc.

What if you could use the Where operator on events? “Only report mouse clicks Where X > 100”, weird, but it is possible. With the Where operator you can filter events.

Another one I’m going to demonstrate in Javascript is the Delay operator.

$('#input-control').toObservable("keypress").Delay(2000);

// Or...

var observable = $('#input-control').toObservable("keypress");
var delayedObservable = observable.Delay(2000);

What you see here is the declaration of an observable that gets extended with a Delay combinator, which returns a new DelayedObservable. The creation or declaration of an Observable itself is not the exciting part. As a matter of fact nothing actually happens when you create an observable. The interesting part starts when you call the Subscribe method and pass in a function.

$('#input-control')
    .toObservable("keypress")
    .Delay(2000)
    .Subscribe(function (e) {
        // Do something
    });

// Or...

var observable = $('#input-control').toObservable("keypress");
var delayedObservable = observable.Delay(2000);
var observer = delayedObservable.Subscribe(function (e) { });

The Observer

As part of subscribing to an Observable you get back an Observer. I like to think about it as the subscription. The observer gives you an handle on the subscription and makes it possible to Cancel or Dispose your subscription when done.

var observer = $('#input-control')
    .toObservable("keypress")
    .Delay(2000)
    .Subscribe(function (e) {
        var c = String.fromCharCode(e.charCode);
        if (c.toLowerCase() === "q") {
            observer.Dispose();
        }
    });

This code sample shows the creation and ending of a subscription. When the letter Q is pressed, Dispose is called on the Observer and ends the subscription.

Conclusion

In this article we have seen the three most important concepts of Rx. The Observable, Combinators and Observer, where the Observable and Observer are just wrappers around an event and its handlers. The Combinators are the magic fairy dust that provides that mind blowing sensation.

For me the most interesting Combinators are the ones that help me compose/declare complex scenarios in an event based or reactive manner. Useful combinators are Join, Wait, WaitUntil, Until, etc.

I will try to come up with a couple of scenarios that demonstrate these more combinatory combinators, like orchestrating a bunch of AJAX calls with RxJS.

For now I’m open for questions and suggestions. I’m not a super guru specialist in this topic. I’m writing while learning this stuff.

My goal is to really understand and live it and find new possibilities to apply this knowledge.

Thanks! …over and out…

Advertisements

About this entry