JavaScript Promises vs. RxJS Observables

Compare JavaScript Promises and RxJS Observables to find the one that meets your needs.

Read on

Brought to you by @kapehe

1 Like

Let us know if you have any questions on this front :slightly_smiling_face:

The article mentions a lot of talk about performance differences early between eager and lazy approaches, but I’m not seeing any timings that bear this out. I am reading on mobile so perhaps I’m missing something?

I’m sure @kapehe will cover that once she’s online!

Hi @steve.hebert! Thanks for reading! The eagerness for Promises is that the .then() is ran right away, whereas an Observable only runs when called upon in the .subscribe(), making it lazy.

It may not be a speed issue for your project but is something to keep in mind when comparing the two. :raised_hands:

Thank you @kapehe, performance is a really interesting topic because a lot is misunderstood on both cases. In building out a discrete RP to pair with Auth0, we were torn between using RxJS and standard promises until we laid it out on paper.

Interestingly, the .then(...) clause is every bit as lazy as the Observable pattern in rxjs. The only way we could get measurable difference was to put a massive number of calls to even articulate a difference between the node runtime variance and rxjs introduced variance. The variance was so small and the code path readability/testability difference was significant enough that we went with Rxjs.

It would be fun to see an article on a relying party provider for Auth0 and hammer on it for performance numbers. But that may just be me. :grinning:

Nice article - keep up the good work and thank you.

1 Like

Thanks for the feedback Steve!

While common, the question itself misleads. It’s equivalent to saying “bitmap vs Unicode”.

Both replace pre-existing patterns of using raw callbacks, but their use cases are very different.

Promises are for co-ordinating async work, i.e. cases where one has multiple, ordered steps (occasionally in parallel). i.e. do start step A, wait for it to complete, then start step B, wait for it to complete… etc. Basically, cases where one just needs to do regular imperitive coding that just happens to have some steps that will be invoked via a callback/are async.

RxJS Observables are typically used (for instance, as in Angular) as a way to do clean event processing, especially when it’s necessary to co-ordinate multiple events/outputs using a Functional programming paradigm.

More generically, RxJS is a functional programming language specifically designed to handle temporal inputs/outputs. i.e. normally we think of functional programming as taking a set of inputs and returning a set of outputs. But in RxJS land, those inputs can have a defacto extra dimension of time. MarbleTesting is an example of what happens when you make explicit that extra dimension.

While there are some edge cases, such as: should you simple do something when a promise resolves, or does that promise resolution represent an “event” that should be subscribed to, most of the time it should be pretty clear which is the right model, and a use for both will exist in any given code base.

Thanks for the article!!

My biggest problem with how observables are used in this case, is that the Observer pattern has a pretty specific use case. It’s a many too many event distribution pattern. Example of a common pattern used for the Observer is…

EXAMPLE: I have 4 components on the screen, each component cares about different Stock Quotes, some could care about the same stock quotes, doesn’t really matter. Then you have a single service that manages the intake of quote data, and each observer subscribes to specific stock quotes.
The Observer creates a really clean way of handling many events that need to flow through your system.

My complaint is specifically with the way I see the Observer being used for an Http Call. An http call is a request/response, one to one. Why do I need an observable for a one to one request. This is a simple call, wait, response pattern that a Promise already provides. IMO it doesn’t necessitate an Observer pattern. And compounding that is that this pattern sets up a completely new observer pattern for every single http call in the system.

Now, I’m not going out on a limb and saying that this is a wrong use case for the Observer Pattern. It still provides a clean, reproducible, consistent, and testable pattern to make your HTTP calls. And that is a VERY important thing! Observers on HTTP calls just feels like a forced use case of the pattern, when a simple, common way of doing this already exist, Promises (or async/await).

Thanks again for the article. Sparks good conversation.

Hey there @kapehe!

Can you look at that? Thanks!

Thank you for sharing Kapehe!
I was looking for a comparison between Promise and Observable from the point of view of performance, bub didn’t found it here?

What do you think about it? Isn’t it obvious that Observable has a higher performance cost because of the listener?

If I’ve a request to REST API save() which returns a JSON object Response {message: string, error: string}, do you not think that Promise will be better than Observable as a return type since there is no others values to wait for from the observable? So, is using observable here makes sense?