1. What is RxJS
According to the official documentation, “RxJS is a library for composing asynchronous and event-based programs by using observable sequences“.
In other words, RxJS is a library that helps us manage and manipulate data over time.
Peaches on a conveyor belt create a stream of peaches. We don’t know how many peaches we will get over some time, or when they will stop coming. However, we may want to do some operations on those peaches. For instance,filter the good ones from the bad ones.
In the world of RxJS, the peaches are data that we may want to manipulate. A stream of data is called an Observable stream.
We don’t know how many “pieces of data” we will receive over a period of time, or when we will stop receiving data. However, RxJS offers an extensive set of operators to manipulate data.
Why do we need RxJS to manipulate data?
Briefly, we could argue that this library offers several advantages compared to traditional techniques like Promises or async/await.
In particular, RxJS can produce multiple values over time and it uses a push model to notify the application when specific events occur. This is at the core of reactive programming.
Moreover, it is possible to cancel async operations before they terminate, unlike Promises.
What is Reactive Programming?
From a theoretical point of view, Wikipedia defines reactive programming as “a declarative programming paradigm concerned with data streams and the propagation of change“.
In other words, Reactive programming is simply programming with asynchronous data streams. Anything can be a stream: variables, user inputs, data structure, etc. Therefore, it is possible to listen to the stream and react appropriately.
When we combine the functional paradigm with reactive programming we want to dynamically specify the behavior of values when we declare them.
Thanks to RxJS operators, we get a set of tools to merge, filter, and manipulate data streams.
- RxJS is a library to handle data over time
- Some advantages over traditional techniques include the possibility to produce multiple values over time and cancel async operations
- Reactive programming is programming with asynchronous data streams.
2. Why RxJS? RxJS vs Promises
RxJS is a library that helps us manage and manipulate data over time. This often involves asynchronous operations.
Despite there being other techniques for managing asynchronous and event-based data, we may want to use RxJS.
Let’s briefly review some of the traditional techniques to handle asynchronous and event-based data. After that, we compare those techniques with RxJS.
Call back a function after an asynchronous operation completes. Callbacks can be difficult to manage when working with many async operations or when those operations are nested into each other. You may want to avoid callbacks hell.
“The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value“, MDN. However, a promise can only handle one single value and it is not cancellable.
“The async and await keywords enable asynchronous, promise-based behavior to be written in a cleaner style, avoiding the need to explicitly configure promise chains“, MDN.
As reported on MDN, the “purpose of async/await is to simplify the syntax necessary to consume promise-based APIs.” Therefore, async/await is based on Promises and this syntax has the same characteristics as Promises.
Async/await can only handle a single emission and it is not cancellable.
RxJS (Observables) vs Promises
Despite not having introduced Observables yet, we can think of Observables as “the Promises of RxJS”. For the moment, this is sufficient.
Since RxJS is a library, it is not possible to compare RxJS with Promises. However, it is possible to compare “the Promises of RxJS”, i.e. Observables, with traditional Promises.
As reported by angular.io, there are some key differences between Observables and Promises.
While Promises return one value, Observables can provide more than one. “This makes observables useful for getting multiple values over time“.
While Promises execute on creation, Observables won’t start to execute until we want them to start. To invoke an Observable and get one or more values we need to subscribe to it. Observables are lazy, Promises are not.
There are more differences, but these are enough to draw some conclusions on why RxJS might be preferred over traditional Promises.
- One library for many purposes. We can use one library to work with any type of data using the same operators. e.g. multiple data sources, events emitters, and APIs.
- Composition. It is possible to combine data from several sources as we like.
- Watchful. RxJS can produce multiple values over time and it uses a push model to notify us when specific events occur. This allows for reactive programming as it is possible to watch and react to users actions and changes.
- Lazyness. Evaluation doesn’t start until subscription.
- Built-in errors handling
- Cancellable. Unlike Promises, it is possible to cancel async actions.
3. What are Observables
Observables are data over time. They are a data source.
How do we use Observables?
- Subscribe to the Observable. An Observable is a data source but it doesn’t emit any data until you subscribe. For this reason, we say that Observables are lazy. Subscribe to an Observable by using the aptly named subscribe() method:
- Start receiving data. Once you subscribe to the Observable, you will start to receive some data. You will keep receiving “data packages” until you unsubscribe from the Observable. However, you don’t know exactly how many “data packages” or when you will receive them. For this reason we say that Observables push values. You can think of Observables like a stream of data over a period of time.
- Unsubscribe. Finally, when you don’t need any more data you unsubscribe using the unsubscribe() method:
myObservable.unsubscribe(). This is important to prevent memory leak. Note that when using an Observable created by Angular it is not necessary to unsubscribe because Angular handles unsubscription automatically. E.g. params observable in the context of routing.