DEV Community

Cover image for Illustrated JS: Promises
Marina Costa
Marina Costa

Posted on

Illustrated JS: Promises

While learning JavaScript and programming in general, I find it useful to create some analogies to understand the concepts better. Here I will share an analogy about Promises in JavaScript. Feel free to contribute in the comments.

In Javascript, if we want to call a function only after an asynchronous function returns, we can use callbacks. Let's say I'm baking a cake with chocolate icing, in that case, my bakeCake() function is asynchronous and takes prepareIcing() (that's the callback) as an argument, calling it only when the cake is completely baked.

Drawing of a baker responsible for baking the cake, calling the one responsible for preparing the icing


Fig.1 - The baker responsible for the baking cake action is calling back the function responsible for the icing preparation after the baking is finished

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.

Drawing of a baker saying: Sounds complicated, right? Let's try again with a simple cake


Fig.2 - My baker likes to use cakes to explain stuff

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.

Drawing of an oven and the possible states for the cake promise


Fig.3 - The oven is a promise of a cake that starts with a pending state and let's me know when it's fulfilled (success cake) or rejected (failure cake)

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. πŸ˜‚

Drawing of an oven and the possible states for the cake promise, including handler for success (serveCake()) and failure (orderPie())


Fig.4 - If cakeBake() is fulfilled, then call the success handler, the serveCake() function. Otherwise, we catch the reason (burned cake) for the rejection and call the failure handler, the orderPie() function

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.

Drawing of chained promises and handlers for success and failure


Fig.5 - Promises chained with .then() and catch() to handle successes and failures

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 coverCake() function.

Drawing of promise all example


Fig.6 - Promise.all() handles both the promise of the cake and the promise of the icing before covering the cake

Inside 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 .then(), .catch() and 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 .then() or .catch().
  • Promise.all() waits for all the promises to be resolved. If any rejects, it's rejected.

References and recommended further reading

Top comments (12)

Collapse
 
kosich profile image
Kostia Palchyk

Ah, yet again a great illustrated article, Marina!

And one can simultaneously start (baking cake & preparing icing) aand order a pie! Then eat the first that's available (Promise.race)!

Warning: don't try to do that at home, you'll end up with both: a cake and a dessert πŸ™‚

btw, Marina , did you know that you can create series of articles in dev.to? press "edit" -> open the "nut" πŸ”© menu at the bottom -> add text to series field

Collapse
 
marinafroes profile image
Marina Costa

Thanks, Kostia! Yes, I thought about including Promise.race() in the example, then I realised it could be confusing. Like you said, in "real life" you'd ended up with both the cake and the pie, right? 🀣 Unless you cancel the delivery or throw away the unfinished cake (not a good idea).

And thanks for letting me know about the series of article, I didn't know that. πŸ˜€

Collapse
 
mattcale profile image
Matthew Cale

Really excellent post :) Thank you.

Collapse
 
marinafroes profile image
Marina Costa

Thanks, I'm glad you liked it. :D

Collapse
 
schnubb profile image
Schnubb

when I try to bake a cake, it always ends with ordering... so bad at baking cake..

Collapse
 
marinafroes profile image
Marina Costa

Same here! I don't even bother trying to bake the cake, I go straight to the point and order something. πŸ₯§ πŸ˜…

Collapse
 
abhayselva profile image
abhayselva

Fantastic,explanations were really good!
THANK YOU!

Collapse
 
marinafroes profile image
Marina Costa

Thanks, happy to read this. :D

Collapse
 
racquelsimone profile image
Racquel WS • Edited

This was helpful. Newer to programming and had seen β€œPromises” when reading, but hadn’t looked into them yet.

Collapse
 
marinafroes profile image
Marina Costa

Thanks, I'm glad it helped. :D

Collapse
 
davidbruchmann profile image
David Bruchmann

Greatly visualized ;-)

I'm missing a bit concrete code where the different combinations are shown, nevertheless it's a good start with promises for me ;-)

Collapse
 
sumusiriwardana profile image
Sumudu Siriwardana

Great article, Marina! Love the illustrations!