bakeCake() function is asynchronous and takes
prepareIcing() (that's the callback) as an argument, calling it only when the cake is completely baked.
But in this article we're focusing on using Promises. So how promises can help solve this problem? A promise is an object that wraps an asynchronous action and can be fulfilled with a value if the operation is successful or rejected with a reason, if it fails. This way I'm able to add a handler for a value (or a reason) that I will have only at some point in the future.
Going back to the baking example, I can say my oven is a promise of a cake, because it wraps my baking cake action and starts with a pending state (it's still baking). But I have a smart oven that will tell me when the action finishes. If the baking was successful, it's fulfilled with a cake. Otherwise, it's rejected with a burned cake or any other reason for the failure.
Like we said before, using promises, we can add handlers for its possible states when it settles (it is either fulfilled or rejected). The
.then() method can handle both success and failure (less common), and the
.catch() method only can handle failure.
This is how I would handle a baking simple cake (no icing) action: if it is successful, then I can serve the cake. But if I burn my cake, I can catch the failed cake, throw it in the garbage and order a pie for my dessert instead. 😂
Another thing to keep in mind is that, since one promise returns another promise, they can be chained. In my previous cake with icing example, I can finish baking my cake, then prepare the icing, then with both the cake and the icing ready, cover the cake. In that case, if any of the promises in the chain fails, I can handle all the rejections with only one catch and order a pie.
But there's a better way to do what we did in the last example. My
bakeCake() and my
prepareIcing() functions are independent, which means they can happen at the same time. For that, we can use
Promise.all() to wait for both results (cake and icing) before executing the
Promise.all(), if any of the promises rejects (fails), the entire promise is rejected. Which makes sense, right? I can't cover the cake if either the cake or the icing is missing.
This was a very simplified and summarised explanation of the concept of Promise, and the use of
Promise.all() methods. I hope it was clear enough.
Thanks for reading, feel free to contribute in the comments. I promise my next article is already in the oven right now (pending). And eventually, I'll share it on my twitter as soon as it's fulfilled or I'll post pictures of cats if it's rejected.
Bullet points for this article:
- Promises are objects wrapping asynchronous actions.
- Promises start with a pending state, and at some point in the future they settle to a fulfilled (success) or rejected (failure) state.
- A promise returns a new promise that can be used for chaining.
- We can add handlers to the success value or the failure reason once the action returns, by using
Promise.all()waits for all the promises to be resolved. If any rejects, it's rejected.
References and recommended further reading