The concept
To understand Observables you first need a thorough understanding of handling asynchronous data, because Observables let you process asynchronous data.
An Observable produces a stream of data. The important word here is stream, which represents multiple values coming in over time. It can even be an infinite amount of values. Promises are not capable of doing that.
Where is that data coming from? From all kinds of sources: For example a server sending data to the browser, a user clicking a mouse button (one or multiple times) or a custom event that you created yourself.
When should you use Observables instead of Promises?
Use Observables if at least one of the following requirements match:
- You need to process multiple values that are sent over time
- You would like to cancel pending data requests easily
- You want to make use of convenient functions to process “incoming” data, such as sorting, filtering etc.
- Your framework
forcesasks you to use Observables
In all other cases I recommend using Promises.
Example: Creating an Observable and receiving its data
In the following example we will create an Observable that emits the string ‘hi’ every second. Then we retrieve the values and log them to the console.
Step 1: Installing RxJS
First thing to know: Functionality to deal with Observables is not built into the browser yet (as of mid 2019), so we choose to install RxJS:
npm install rxjs
Step 2: Creating the Observable
Starting from line 3 we create an Observable that produces the string ‘hi’ every second. So this represents an infinite data stream.
import { Observable } from 'rxjs'; const observable = Observable.create((observer) = { const id = setInterval(() => { observer.next('hi') }, 1000); });
Step 3: Receiving data
You have to call subscribe() on the Observable and pass it a function. Only then will the Observable start to push values to the Observer over time.
observable.subscribe(x => console.log(x));
Now the console logs ‘hi’ every second.
The subscription stays active unless an error occurs, the Observable completes the process of pushing data or the Observer chooses to unsubscribe.
Side note: If multiple Observers subscribe to the same Observable, then the Observable code runs independently for each Observer.
Push vs. Pull
There are two ways how information travels from a Producer (of values) to a Consumer, push and pull:
- A Consumer (active) pulls data from a Producer (passive).
- A Producer (active) pushes data to a Consumer (passive).
On top of that, data that comes back can either be a single value or it can be multiple values. This leaves us with a combination like this:
Single value | Multiple values | |
Pull | This is what any JS function does: It produces a single value. When you call a function, you pull that value. | An Iterator produces either a finite or infinite amount of values. |
Push | When a resolved Promise calls the caller, it pushes a single value | Here is where an Observable shines: When a consumer subscribes to an Observable, the Observable can push multiple values |
Observable vs. Promise
So you have heard of or used Promises and wonder what is the difference to Observables? Are Observables better? Are Promises outdated? No, they just serve another use case.
Observable | Promise |
---|---|
Emits multiple values over time | Provides a single future value |
Can be cancelled | Cannot be cancelled |
Lazy | Not lazy |
Supports operators to manipulate incoming data, such as map, filter, reduce… | No support |
No comments yet.