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
asyncpipe 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
Promiseis something that will publish a value in the future. -
The
resolvefunction is used to publish that value. -
The
thenmethod is used to listen for that value. -
Only one value can be published.
-
Works asynchronously.
Observables
-
An
Observablelistens for values published by a source. -
The
subscribemethod is used to listen for values. -
SubjectandBehaviourSubjectpublish values using theirnext,completeanderrormethods. -
rxjs provides methods like
from,Of,fromEventandfromEventPatternthat publish values.
Hot Observables
-
An
Observablethat 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.