A quick overview of when and why to use RxJS, and how you could maybe, kind-of do the same thing in vanilla JS
RxJS is cool and increasingly popular, but it seems like there’s a fair bit of confusion around when and why you would use it. “Why would you ever need that?”, your coworkers might say to you.
I’m no RxJS expert and I don’t think it’s needed for every project, but for me, the main reasons to use it are that it allows you to:
- Easily compose multiple events into one.
- Declaratively transform the value emitted by an event sequence in a functional, lodash-esque style.
- Better model asynchronous data flow. Keyboard input, AJAX requests, events from an event emitter, etc. are all asynchronous and produce values over time. Representing that with the same interface has a lot of value.
Let’s look at an example that demonstrates those bullet points.
Show me teh codez
So we want to create an event emitter that emits true/false when a user’s internet goes online/offline. Quite a few applications have this functionality, so it seems like a good example.
The requirements of what we’re trying to create is:
- call the provided callback initially with the current online/offline status
- emit true/false when online/offline
- support multiple subscriptions (aka multiple callbacks registered to the event)
- support unsubscribing a subscription
- unsubscribe from underlying event sources if there are no subscriptions
- don’t subscribe to event sources unless there’s a subscription
We’ll do the vanilla JS version first. The caller of this event emitter might look like this:
const onlineEmitter = createOnlineEmitter();
let unsubscribeFn = onlineEmitter(
isOnline => console.log(isOnline)
//the callback function gets called initially with value of isOnline
//and every time it changes after
The vanilla version is a little long and somewhat complex due to all the bookkeeping you have to do.
While I like the vanilla version, and it functionally does the same thing that the RxJS version will do below, it’s main drawback is that it’s not composable or flexible at all. It does it’s one thing and that’s it.
How does that look in RxJS?
The caller of the RxJS version will look something like this:
const online$ = createOnline$();
online$.subscribe(isOnline => console.log(isOnline));
//callback function has same behavior as the vanilla version
So similar to the vanilla one, but not exactly the same. Here’s the implementation:
So, quite a bit smaller, which is to be expected.
But to demonstrate the composability advantages of the RxJS version that would be harder to achieve with the vanilla:
That’s a simple example but there’s a lot of possibilities because Observables can so easily be composed and combined together to form new ones. Hopefully this demonstrated some of the value they can bring to an application.
Here’s a plunkr of the examples above:
RxJS vs vanilla comparison - Plunker
Open the console and go to script.js console.clear(); window.onload = init; // Vanilla version function…
(To play around with the online/offline event, open Chrome’s dev tools, go to Network, and toggle the “Offline” checkbox).