Understanding RxJs
Reactive Programming can be extremely difficult to understand. Here is a quick introduction to RxJs to hopefully get you started using reactive programming.
What Is An Observable?
An Observable is, in the simplest form, the result of an asynchronous operation. We can use them in place of Promises for a lot of asynchronous tasks. However an Observable allows for us to do complex logic on an async data stream with only a few lines of code.
The Basics
Before we get to the complex work we can do with Observables we should first understand the basics. There are a lot of helper methods to create Observables, for this example we will make use of interval(period: number)
. It creates an Observable that returns an incremented number every period
milliseconds. Creating this observable is as simple as:
interval(1000);
This Observable will "emit", the term used for when an Observable produces a new value, the following 1 (one second) 2 (one second) 3...
.
Subscriptions
In order to get the emitted values from the above Observable we will need to "subscribe" to it.
const source = interval(1000);
source.subscribe(value => {
console.log(value);
});
The above code will print out the emitted values as they are emitted from the Observable.
The Idea of the River
I find that when working with Observables it often helps to think of the "source" Observable as a river, with each emission being a boat that is floating down the river. By Subscribing to an Observable we are being given access to see the boats that are on the river. Next we will learn how to manipulate how and when those boats are perceived by someone watching the river.
The Pipe Operator
Here we are going to get into the more complex things we can do with Observables. We can achieve this using the pipe()
function that exists on an Observable. Taking the source
from above we can create a piped observable that only passes along even numbers.
const source = interval(1000);
source.pipe(
filter(value => value % 2 === 0)
)
.subscribe(value => console.log(value))
This will print out 2 ... 4 ... 6 ... etc
. We can see that the Observable has operators that can act upon the emitted values. Here we use filter(select: Function)
to only accept values that are even. This is similar to the filter()
function on arrays in JavaScript.
There are a load of pipeable operators that we can make use of.
Assume we have an Observable who's source is click events:
const source = fromEvent(document, 'click');
This will create an Observable who will emit every time there is a click
event on the page.
Now say we need collect these click events into batches of 5 and then send them off to an arbitrary API for processing, which will then return a value from that processing which we need to print out, we will assume we have a service written that is ready to make the API call since that is out of the scope of this article. Here we can make use of the bufferCount(bufferSize: number, startBufferEvery: number = null)
to do this.
const source = fromEvent(document, 'click');
source.pipe(bufferCount(5))
bufferCount(5)
will collect 5 emissions from source
and then emit them as an array. Now that we have our events batched we need to send them off to the API. Our service will return an Observable from its service call, so we need to take the value from our source and pass it to a function that makes a new Observable, and then return the new Observable. We can make use of the mergeMap()
operator.
const source = fromEvent(document, 'click');
source.pipe(
bufferCount(5),
mergeMap(events => this.myAPIService.serviceCall(events))
)
.subscribe(processedEvents => console.log(processedEvents));
In a few lines of RxJs operators and functions we have created some, albeit odd, logic that could take many more lines to complete with Promises.
Conclusion
RxJs is an extremely powerful tool that can be extremely difficult to grasp, especially when working with large applications that retrieve data from multiple locations. I hope this article has helped shed some light on how Observables work. Feel free to drop any comments, questions, or concerns in the comments below.
Additional Resources
When I am working with Observables I often check learnrxjs.io. They have a list of Operators with examples and explanations of the operator. There is also a list of recipes showing the operators in action.
The official docs also contain useful information including marbles diagrams, which we will cover in the next article, and examples.
Top comments (0)