Reactive programming is a general concept that you can find in any language, it is often associated with event driven UI, asynchronous programming with observable, where you can subscribe to events. Reactive Extensions (abbreviated Rx*) provides libraries for a wide variety of programming languages, including JavaScript (RxJS). RxJS it precisely that, an extension/library for JavaScript.
- What is Reactive programming RxJS?
- But wait, what is an observable?
- Anything can be a stream
- Where can I use RxJs?
- Try yourself
- RxJS Observables vs Promises
- RxJS integration with AngularJS.
- Differences between RxJs and Knockout
- Conclutions
What is Reactive programming RxJS?
Reactive programming RxJS or Reactive Extensions for JavaScript is a reactive streams library that can be used in the client-side in the browser or server-side with Node.js. to work with asynchronous data streams. From the perspective of JavaScript let’s analyze the last three words of the previous sentence: asynchronous – data – streams.
Asynchronous – Is the fact of calling a function and then register a callback when results are available, this way we are notified about the returning of that function and been able to continue with execution avoiding non responsive behavior in our page.
Data – Raw information represented by any data type: Number, String, Objects.
Stream – Data made available over time meaning that you don’t need the presence of all the information to start using it for example mouse clicks, user inputs, database queries or just the call to an API.
But wait, what is an observable?
Observable is a JavaScript implementation of the observer pattern (also known as ‘publish/subscribe’).
The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.
It is mainly used to implement distributed event handling systems.
Anything can be a stream.
Taken from this great article of Gerard Sans.
Asynchronous data streams are a pretty old concept, it exists since Unix and take different names and behavior depending on the environment for example in Node.js they are called ‘streams’, ‘pipes’ on Unix and ‘async pipes’ on Angular 2.
reactive programming: programming is called reactive when you are working with Asynchronous data streams.
Using RxJS asynchronous data streams can be represented through Observables and manipulate those streams with different operators as if they were simple collections of data. Next section has some examples.
Where can I use RxJs?
Creating and subscribing to simple Observable sequences
First include rx.js file in your code, you can use a CDN https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.3/Rx.js:
<script src="rx.js"></script>
If using Node.js:
var Rx = require('rx');
Lets create a very simple example so you get the idea of how it works.
For this we are going to create a textarea (the stream acting as event generator) we are going to show to the user what we are writing in the textarea plus a fixed text (this is the reaction). This is going to looks like a data-binding between the textarea and the label.
<textarea></textarea> <p> <strong>Text:</strong> <code id="text"></code> </p>
const text = document.getElementById('text'); const area = document.querySelector('textarea') const content$ = Rx.Observable .fromEvent(area, 'keyup') // each `keyup` throws an event on the stream // shows the content of the text area concatenated with the string ‘Fixed text’ .map(e => e.target.value.trim() + ' Fixed text');
The suffix $ on the variable named ‘content’ it used to indicate that the variable is a data stream.
So, the data stream ‘content$’ will launch a new event each time the user inputs a new letter. The correct way to react to this constant stream of data is through the function “subscribe()” like this:
content$ .subscribe(text => { console.log(`The textarea content is: ${text}`) text.innerText = text;//print the text. });
Now that we got the idea lets implement something more practical like a "word counter", in order to obtain the amount of words, we need to update the stream and update the user interface to show how many words are written. To do this we need the function ‘map()’ which is one of the many operators provided by RxJS (a full list of RxJS operators can be found here):
content$ .map(content => content.trim().split(' '))// make the string into an array of words .map(wordList => wordList.length)// count the array elements .subscribe(totalWords => { text.innerText = totalWords })
Each step is transformed into stream and return a modified object to the next step. Finally we are going to use the function ‘subscribe()’ where we indicate what is going to be the reaction, in this case, the reaction is to update the user interface to show the amount of counted words.
Try yourself (full code):
I recommend you to read this tutorial for better understanding of the subject:
The introduction to Reactive Programming RxJs you've been missing
What operator to use
RxJS Observables vs Promises
Promises is a concept from javascript async programming. Basically the Promises give an abstracted help to work with asynchronous matter’s inside the apps. The promise is the eventual result of an asynchronous data stream task. For better understanding read this and analyze the example code text taken from here:
“The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled. You can create them very easily where the constructor has two functions, resolve and reject which resolves the value or rejects it for a given reason “
- Observables are cancellable. Observable also has the advantage over Promise to be cancellable. If the result of an HTTP request to a server or some other expensive async operation isn't needed anymore, the Subscription of an Observable allows to cancel the subscription, while a Promise will eventually call the success or failed callback even when you don't need the notification or the result it provides anymore.
- The main difference here is that Promises in order to be able of retry the call, the caller must have access to the original function that return the Promise. In the other hand Observables are cancellable and the API provides operators to retrieve them (‘retry’ function).
- A Promise handles a single event when an async operation completes or fails.
Note: There are Promise libraries out there that support cancellation, but ES6 Promise doesn't so far.
RxJS integration with AngularJS.
You may write a custom helper function to integrate this two but as you also may expect this task is already done. A library called rx.angular.js is in charge of this interoperability. Let’s analyze an example of using DOM-events:
To be able of use DOM-events we are going to use Rx.DOM, an HTML DOM bindings for RxJS provided by rx.angular.js. The next code is a feature to detect the time of inactivity of the user.
mergedStreams = rx.Observable.merge( // mergin all the events coming from the user rx.DOM.keydown(document), // keystrokes rx.DOM.click(document), // mouse click rx.DOM.mousemove(document), //mouse move rx.DOM.scroll(document), //scroll rx.DOM.touchstart(document) // taps ); var idleStream = mergedStreams .bufferWithTime(5000) //operator bufferWithTimes to catch all the event in buffer .filter(function(arr){ //to check when the sequence is empty to notice that user is gone. return arr.length===0; }) .subscribe();
For more examples of how to integrate AngularJs with RXJs visit here:
https://github.com/Reactive-Extensions/RxJS/blob/master/doc/howdoi/angular.md
Differences between RxJs and Knockout
The main main difference is:
Reactive programming RxJs allows composing operations against asynchronous streams , like http web requests or events, and includes advanced scenarios like combining streams for example when both event A and event B occur, execute X code, but stop it if B occur again.
KnockoutJs is an MVVM (not MVC) framework, with it you can manage the state of yourUI with a model that maps it's functionality. This allows your to separate the logic from the view and the UI state.
Steve Sanderson, creator of Knockout, explained the difference on his blog:
I’m very familiar with Rx for JavaScript, having recently used it heavily on a big project, and in fact aspects of the design of Knockout are made with my Rx experiences in mind.
The key difference between Knockout’s implementation of the observer pattern and Rx’s is that Knockout automatically infers the associations and dependencies between observable from regular procedural code without you having to specify them up front though a special functional API. I wanted Knockout to use regular procedural/imperative-style code as it’s more familiar and approachable for most developers.
Another difference is that Rx is optimized for composing streams of events without state. At first I was enthusiastic about this and its functional purity, but after some time it felt increasingly like I was jumping through awkward hoops and had to invent extra ways to simulate state to manage UI commands efficiently. That’s why, in Knockout, all observables can be treated as stateful - for example you can always read their latest value (which is cached, by the way - it doesn’t recompute until the underlying data changes).
Rx goes further than Knockout into advanced ways of composing event streams, whereas Knockout goes further than Rx into UI development, letting you bind its observable to HTML DOM elements and templates and manipulate them any way you want. Rx is great at what it does but turned out not be be exactly how I wanted to build rich UIs - hence the design of Knockout.
Conclutions
I hope this article can be used as a starting point to dive into reactive programming for javascript RxJs, I encourage you to keep researching and learning about it since the intend of this post is to introduce the concept and make a comparison with other libraries like KnockoutJs, etc.