Observables or Promises
Introduction
Personally, I prefer working with Observables over Promises.
There are 3 reasons for it:
-
I do not create libraries. I work on applications.
-
Angular provides the
async
pipe for working with observables. -
Consistency. If you know that your functions will return Observables there is just one way to handle it.
So, most of the time, if I encounter a library that exposes its functionality using Promises, I create a wrapper class around it that returns Observables.
Now, there are rules that one must remember when converting Promises to Observable. We will discuss these rules later in the post.
First, we clarify a few concepts.
Concepts
Promises
-
A
Promise
is something that will publish a value in the future. -
The
resolve
function is used to publish that value. -
The
then
method is used to listen for that value. -
Only one value can be published.
-
Works asynchronously.
Observables
-
An
Observable
listens for values published by a source. -
The
subscribe
method is used to listen for values. -
Subject
andBehaviourSubject
publish values using theirnext
,complete
anderror
methods. -
rxjs provides methods like
from
,Of
,fromEvent
andfromEventPattern
that publish values.
Hot Observables
-
An
Observable
that does not need a subscription to publish a value. -
A mouse click or a keyboard event are examples of hot observables as they keep publishing events regardless if someone is listening to them.
Cold Observables
-
A cold observable only publishes a value on subscriptions.
-
An Http request is an example. It only sends a server request when someone subscribes to it.
Rules to consider when converting Promises to Observables.
Using from()
const observable$ = from(getPromise());
-
This is a hot observable.
-
It is a hot observable because the producer (the Promise) is created outside of the Observable.
-
The promise executes immediately and the value is published.
-
All subscribers share the same promise and will receive the same value.
Using defer()
const observable$ = defer(()) => getPromise());
-
This is a cold observable.
-
It is a cold observable because the producer (the Promise) is created inside of the Observable.
-
The promise is executed only when someone subscribes to it.
-
Each subscriber gets a new promise and potentially a different value.
Using other operators
-
RxJS operators that combine (e.g. merge, concat, forkJoin, combineLatest …) or transform observables (e.g. switchMap, mergeMap, concatMap, catchError …) accept promises directly.
-
If you’re using one of them anyway you don’t have to use from to wrap a promise first
-
Check the documentation for appropriate usage.
Conclusion
In summary, based on the scenario, you need to decide if you need a hot or cold observable or use one of the existing RxJS operators.