In Angular, you can perform asynchronous actions in two different ways, Observables, and Promises.
Most people pick Observables because every example on blogs and documentation tells you to do so. But why? Are Promises that bad? Or Observables that good?
In this post, I want to dive with you into the why! Why and when should we use Observables, and when are Promises just fine.
Let's start with comparing the two with each other.
Observables VS Promises
Let's start with the Observables.
Observables
Angular is using under the hood RxJS. RxJS comes with a great set of features like Observables.
Observables can perform asynchronous and synchronous actions in comparison to Promises. Promises can only perform asynchronous actions.
When Observables are created, it does nothing until a piece of code decides to subscribe to it. You can cancel a subscription to Observables, or when an error is happening, it's automatically unsubscribed.
Observables handle a stream of values. It updates very quickly at a later point in time.
To summarise:
Observables behaviors
- Multiple values
- Can be canceled
- Great for real-time information
- Can be subscribed to from multiple places
- Errors unsubscribe automatically
- Observables are declarative. They are only performed when something is subscribed to it.
- Have a built-in mechanism to perform transformations to the data (map, forEach, filter, reduce, retry, and retryWhen operators)
- Can be both asynchronous and synchronous
Promises
A Promise is a general JavaScript concept introduced since ES2015 (ES6). It's ideal for performing asynchronous actions. It doesn't have subscribers like Observables.
A Promise can't be canceled like an Observable. It can be resolved or rejected, nothing more, nothing less. It can handle single values instead of a stream of values.
Promises are performed on creation instead of subscription like Observables are.
If you want to learn more about Promises, check a more detailed post I wrote earlier
To summarise:
Promises behaviors
- Single value
- Can't be canceled
- Great for single time information
- Can't re-use or distribute information
- Promises are performed on the creation
- Is always asynchronous
When Use A Promise Or Observable?
As we saw earlier, the most significant difference between a Promise and an Observable is handling a single value and a stream of values.
Use A Observable
An Observable is ideal for situations where the data changes during its lifetime.
Situations to use
- Real-time data from a WebSocket, for example. Think about dashboards, chat messages, notifications, video subtitles, sound visualizations.
- Or actions that are performed very often by a user. For example, think about collapsable menus, dark and light modes.
These situations require data to update in a short amount of time, at least in the same lifetime of the subscriptions.
Use A Promise
Since a Promise can handle a single value, there are pretty many situations to use it.
Situations to use
- Forms submission: Creating, editing, and deleting data entities don't require a constantly updated stream of data. The form data is sent to the API; it's successfully done or not.
- API requests for data that doesn't change real-time: a large amount of data to show an overview page or a detail page
All of these situations don't require that data to change that often. Data is collected by an API call, displayed, and done. It's that simple.
Why Is Everyone Using Observables For Everything?
So this raises for me the question. "Why is everyone using Observables for everything?"
Yes, I'm guilty on this topic myself! I have done singular requests using an Observable. Was it needed? No!
Keeping a subscription open, while the data is not changing in the lifetime of that Observable, is not correctly using the power of a browser. Besides that, most developers (myself included) will forget to unsubscribe from their Observable quite often.
My rule of thumb mostly is: "If you don't need it, don't include or use it!"
Let's not waste our resources but use everything for its purpose.
Summarize
Okay, let's make this easy for everyone.
Use an Observable for data that is changing real-time or more often during its lifetime. Don't waste resources! Use A Promise if the data isn't changing during the lifetime of a component!
It could be possible that I'm missing the point or being wrong π . Would you please let me know in the comments what I'm missing?
Thanks!
*I hope you learned something new or are inspired to create something new after reading this story! π€ If so, consider subscribing via email (scroll to the top of this page) or follow me here on Hashnode.
*
Did you know that you can create a Developer blog like this one, yourself? It's entirely for free. ππ°ππ₯³π₯
If I left you with questions or something to say as a response, scroll down and type me a message. Please send me a DM on Twitter @DevByRayRay when you want to keep it private. My DM's are always open π
Top comments (15)
I really liked the format and art of the article!
I tend to use observables as they are more powerfull than promises, with al the rxjs utilities. But I use them mostly for HTTP requests and such. Though I agree there are some cases as you point out, where promises should be prefered.
Yeah, Observables are very powerful! They offer a great variety of tools to build reactive interfaces. But we should pick the best tool for the job, right π
That's it, picking the right tool for the job. you wouldn't use a toothbrush to clean the house right? :P
π€£π€£π€£π€£ would be a great accomplishment! But yeah true!
According to this post, because Observables are faster.
When I read the post, I can't find actual evidence in what way Observables are faster.
A person on StackOverflow has run a great test to measure the performance of a Promise and Observable. There you can see that a Promise is more performant than an Observable.
But that's not the only point of the Promise vs. Observable debate. Just pick the right tool for the job.
I found this great list on StackOverflow on when to use one over the other; maybe it's helpful to you.
Use Promise instead of an Observable, when:
Use Observable instead of a Promise, when:
Source: StackOverflow
Everything seems to be in Observables in Angular, so after a little experience, you get good at going between the two for your needs. I think it helps you master async techniques in general. I tend to use
.pipe(take(1)).toPromise();
all the time, but never go from Promise to Observable. As you said, they have different uses, depending on the data source.The test right under that, which to me reads as a better test anyway: Observable wins.
Interesting article, thanks! A doubt: for http requests do you use HttpClient and return a toPromise() of that? (...so your article pops out others questions... as far i can see it's an old and resolved debate about HttpClient :)
Yes, most of the time I use
toPromise()
πObservables are great until you need to make a series of simple API calls in succession. You can use setTimeOut and guess how long each call will take but thatβs pretty janky imo, or you could chain subscriptions, although isnβt that the βcallback hellβ we were trying to avoid with Promises? Or you can still use a series of Promises await them to ensure the succession and then combine them into an observable response? Finally, you can of course just do a straight up promise when you need a pull of non transforming data from the server or a straight up Observable when you have a value that does change over time and is using the server push paradigm. Push vs Pull is definitely the key to understanding when to use each effectively. Thanks for the article, I enjoyed it and totally agree!
I totally agree.
Code, like everything else, should be simple and direct.
In almost 100% of the daily tasks one can use a simple Promise instead of over-engineering with Observables.
Most views are basically (click/event => get results using criteria => show results).
Promises tend to make your code end up looking very similar to the logic, especially with using await/async (click => wait for result => show result), and Observables tend to create indirect implmentations (when the text changes put it somewhere, something else will make sure the results are updated later). For me, indirect implementations are very very bad.
Observables are very powerful for infrastructure-like stuff (like Base classes, global services, etc...) and they should be prefered there.
It's simply another case of the right tool for the job.
While I completely agree with you when you say it's not necessary for everything, I highly recommend developers in my team to prefer Observables over Promises when working with Angular. The top reasons are consistency and flexibility.
Anything you do with a Promise can be done with an Observable, but that's not true the other way around.
Also, you don't need to unsubscribe from Observables which use the HttpClient, which seems to be the only example of extensive use of Promises you've given, but that doesn't free you up from unsubscribing in other situations. That is, nothing has changed.
In the end, I'll stick to Obsevables in my HTTP calls because pipe, map, and other RxJs operators just make my life a lot easier when it comes to preprocessing responses, and is specially helpful when the requests have asynchronous parameters, which is not uncommon.
And last but not least, I'd rather have a new junior developer learn RxJs well to deal with our Angular code base, than having them learn both, if they have that technical debt. They can learn Promises later and that will not be an impediment to deal with our code base.
The only time I make use of Promises is when I don't already have RxJs as an inevitable dependency. For example when I'm writing a simple script or smaller project, and I see it would be overkill to use RxJs. If there are not restrictions I'll use Promises, which are way more elegant than callbacks, but I'll use callbacks if there's a good reason to.
I think not using RxJs for everything in Angular would be similar to writing Assembly code to optimize a part of and application you're writing in C, because of resources or speed. At this point you have to ask yourself: Is that really making much of a difference?
Everyone is entitled to their preferences though.
Well, technically Observable from http request is finite if I recall correctly, so in most cases you can disregard unsubscribe. But yeah, no need to be fixed on Observables alone π€
True, that's the beauty of an Observable. You can unsubscribe to it! π