RxJS – Part 1 – Introduction
All posts in RxJS series:
Introduction to RxJS
Reactive programming is nothing new in programming world. It has been used over 40 years ago or even before that. It started to bloom recently along with micro-services and functional programming. Idea is that we have something that represents a value over time which might constantly change. Most of the time when working with reactive programming we will be dealing with asynchronous programming. Even before Angular 2.0 was released Google or precisely Angular team decided to adopt and use RxJS internally in their framework. Since then it has grown rapidly in popularity.
And what is RxJS ? It is a JavaScript implementation of the ReactiveX library – a library for composing asynchronous and event-based programs by using observable sequences. ReactiveX itself is an abstraction of library that you can use on different platforms and with different languages. In addition to RxJS, ReactiveX has implementations in several other most popular languages. For the full list refer to the languages page on the official website.
Pillars of RxJS
- Producer
- Observable
- Observer
- next
- error
- complete
Subscribing to events
let button = document.getElementById('btnClick');
button.addEventListener('click', onButtonClick);
function onButtonClick(event: MouseEvent) {
console.log(event.target);
}
In ReactiveX an observer subscribes to an Observable. Then that observer reacts to whatever item or sequence of items the Observable emits. This pattern facilitates concurrent operations because it does not need to block while waiting for the Observable to emit objects, but instead it creates a sentry in the form of an observer that stands ready to react appropriately at whatever future time the Observable does so.
Therefore we consider Observable to be a sort of publisher (creator, producer) and Observer is a subscriber (consumer).
Also, with RxJs we can represent multiple asynchronous data streams from different sources as one. We can subscribe to that event stream using the Observer object.
Subscribing to an Observable
Lets see how we subscribe to an Observable:
As we can see on Observer class we have 3 main methods: next, error, complete. Observable invokes Next() method on the Observer object whenever there is a change in the source (array, stream etc.).
Whenever there is a value to produce Observable triggers the next() method.
If something throws an exception and Observable runs into error it will call error() method on Observer.
Once an error happens Observable stops calling the next() method. Furthermore, complete() method will not execute after that.
It is possible that Observable has no more values to produce from data source. In that case Observable calls complete() method on Observer. In simple example above where we have array of strings as data source this will be the case.
In conclusion, error
or complete function
can say that there is no more data to send ot Observer. Only one of them may occur, never both!
If we look at dev console in Chrome we can see the following output:
We can also use functions to subscribe to an observable. It would make more sense in last example to use 3 functions instead of making new class and creating an object instance.
This is how we would do it with 3 simple functions:
And we would of course get the same output as before.
Real world use cases
This looks cool and nice but you are probably thinking why would you even consider learning more about RxJS? Why would you use it in your application?
Some of the obvious examples are pages that use WebSocket protocol. Sites that use chats, messaging, real time graphs and statuses. We probably do not want our users to spam the chat with their messages. On a page with real time statuses we do not want our users to refresh like a madman and send too many requests to our server. Therefore this would be an obvious good use case for RxJS, since it is designed for async data streams. Furthermore, RxJS has tons of operators that can handle async streams and manipulate them in a really nice and fluid way.
Another good use case is type-ahead search. Lets say we have simple notes application with thousands of users online! And users wants to find a specific note, maybe something they saved months ago. If user is typing fast and wants to search our database we certainly do not want to send a request as every user types. We want to handle the input from user and possibly send request only every 500 ms.
More about this in next few posts! If you wanna jump directly to the example of using RxJS in a chat application click here.
Summary
We saw that Observable delivers streams of data asynchronously and it can do so until it exhausts data source or it can continue infinitely in future.
Observable serves as wrapper of producer. On other side we have Observer. Observer is a consumer of the data that gets produced.
Observer has 3 main methods: next, error, complete. Whenever Producer has data to produce it uses next method and sends in value.
RxJS will come in really handy when we use apps that consume real-time data: chat applications, real time graphs, real time statuses. In these apps we probably want to have more control over users input and handling the stream of data to them. It also comes in handy when we want to limit the constant keyboard / mouse input from the user. One common example would be type-ahead search.
That is all for now. In next post we will talk more about Observable and explore some other related concepts. After that we will talk about operators and real-life use cases of RxJS. We shall see some examples of RxJS in real action.
If you want to play around with RxJS you can find the sample code with webpack and TypeScript set up at my GitHub repository – rxjs-playground.