This content originally appeared on Bits and Pieces - Medium and was authored by Vidal Quevedo
The RxJS library helps introduce reactive programming features and Observables to JavaScript. If you are like me, you probably first heard of it while working with Angular, as many of the framework’s features are based on Observables right out of the box.
The concept of Observables can definitely be confusing at first. However, while working with them, I eventually ran into two mental models that finally helped me wrap my head around what they are how they can be used. To this day, these are my go-to frame of reference whenever I need to work with the RxJS library. These mental models are:
- Think of Observables as asynchronous arrays.
- Think of operators as funnels.
Let’s explore these in detail so you can also start using them today!
1. Think of Observables as asynchronous arrays.
RxJS.dev defines Observables as follows:
“Observables are lazy Push collections of multiple values.”
While very succinct and accurate, this definition still leaves out a whole lot of missing contextual concepts to fully understand the practical use of Observables.
Fortunately, at a Meetup talk a while ago, Abraham Williams did a presentation on Observables and Angular in which he displayed a small diagram that became a huge Aha! moment in my grasping of what Observables are. In it, he was addressing the intersection of single/multi-value and synchronous/asynchronous variables. He did this to point out where Observables fit in the picture, breaking it down like this:
This is where it all became clear: conceptually, Observables can be thought of as asynchronous arrays!
Now, what also made things click was not only seeing that they are multivalue variables, but also seeing how Observables differ from Promises. Promises are natively supported in JavaScript to handle single asynchronous values, so once a Promise is resolved, it’s done. For example, the following snipped creates a Promise that returns ‘beep’ when resolved after one second (we then take that string and print it to console).
The main point here is to see that, once the Promise is resolved and won’t emit anything else.
On the other hand, Observables can emit more than one value over time. We can “read” these asynchronous values for as long as we have either subscribed to the Observable, or the Observable itself completes.
For example, the snippet below creates an Observable which emits three strings (‘beep’, ‘boop’, ‘bop’) before completing:
As you can see, the first two values (‘beep’, ‘boop’) are emitted one after another, but the third value (‘bop’) is emitted after ten seconds. During that time, the subscription remains “live,” waiting for something else to come down the stream.
Here’s another example: Imagine that we want to print to console the coordinates of the mouse cursor every time the user clicks on a web page.
We can accomplish this by using the RxJS fromEvent() creation operator, which allows us to create an Observable that emits event data every time a specified DOM element’s event is triggered (in this case, document‘s MouseClick event):
Once we subscribe to observable, it’ll start emitting the event data on each click event. We then print to console the coordinates of the cursor at the moment the click event occurred.
You can click several times in a row, or wait two minutes and then click again, but for as long as the subscription is live, we’ll continue printing the the coordinates.
So, there you have it: an Observable is like an array of asynchronous data.
2. Think of RxJS operators as funnels
Another mental model that helped me better understand how to handle Observables came from this video by Maximilian Schwarzmüller from Academind.
In the video, he suggests thinking of RxJS operators as funnels that take values emitted by an Observable and do something with them before passing them down the stream (e.g. modifying them, creating side effects, etc).
Building on the click event example above, let’s say we now would like to detect double clicks based on how fast the user presses the click button (for this exercise, clicking more than once every 250ms will be considered a double click). When a double click is detected, we then print a ‘double click!’ message to the console. Here’s the code:
As you can see, we’re using the Observable’s pipe() method to set up a sequential, funnel-like list of operators to help us handle each emitted value. However, before we dive into the code, let’s first go over what each of the listed operators does:
- bufferTime(): an operator that “retains” all the values emitted by the Observable for a specific amount of time, and then returns them in an array after the time has elapsed.
- map(): one of the most commonly used operators, map() runs every time the Observable emits a value and allows us to do something with that value. It automatically wraps whatever we return in a new Observable so it can continue being handled down the line.
- filter(): allows values emitted by the Observable to continue going down the stream only if they meet the required filtering condition.
So, now that we know what each one of these operators does, here’s how we are using them in the code above to accomplish our goal:
On each click event:
- Use bufferTime()to start an array of click events and wait for 250ms more to see if any other click events happen, resetting the buffer time on each click. When no more clicks happen after 250ms, return a new Observable with the array of click events.
- Use map()to take the array of values and return a new Observable with only the length of the array as its value.
- Use filter() to only allow the value to continue down the stream if the length of the array is greater or equal to 2(i.e. a “double click”).
- In the subscribe() block, print 'double click!' to console for each event that successfully meets the filtering condition.
As you can see, in this implementation we controlled the flow of values with bufferTime(), modified the values into something easier to work with with map(), and further controlled the conditional flow of values with filter() before reaching the subscribe() block to do what we wanted: print a message to console on each double click.
So there: operators are like funnels that help us handle the flow of the stream of values emitted by an Observable.
Certainly, the list of RxJS operators is pretty large, and it takes a while to understand what each one of them does, but thinking of them as funnels is what has helped me learn how to use them more effectively.
In addition, this mental model has also helped me broadly identify what kinds of operators there are:
- Operators that help you control the flow of the stream (e.g. start it, stop it, throttle it, slow it down, etc).
- Operators that help you modify the data emitted by the stream.
- Operators that help you share the data emitted by the stream.
- Operators that help you combine streams.
- Operators that help you create streams.
Conclusion
Always keep this in mind: think of Observables as asynchronous arrays, and think of operators are funnels that help you control and modify the flow of the stream as needed.
I hope this helps, and happy coding!
Thanks to Mike Guoynes
Build Micro Frontends with components
Microfrontends are a great way to speed up and scale app development, with independent deployments, decoupled codebases, and autonomous teams.
Bit offers a great developer experience for building component-driven Micro frontends. Build components, collaborate, and compose applications that scale. Our GitHub has over 14.5k stars!
Learn more
- Building a React Component Library — The Right Way
- Microservices are Dead — Long Live Miniservices
- 7 Tools for Faster Frontend Development in 2022
The Two Concepts That Finally Helped Me Understand Observables was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Bits and Pieces - Medium and was authored by Vidal Quevedo
Vidal Quevedo | Sciencx (2021-12-29T07:45:22+00:00) The Two Concepts That Finally Helped Me Understand Observables. Retrieved from https://www.scien.cx/2021/12/29/the-two-concepts-that-finally-helped-me-understand-observables/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.