Struggling with Promises? You Are Not Alone!
Tags: javascript, beginners, webdev, programming
Published: 2022-07-03 13:19:09


Do you like to cook? I’m not sure about you, but I enjoy cooking. I usually cook by myself, although I’m not opposed to having some help.

Many times you’ll find yourself in a situation where you will need something in the middle of cooking and that damn thing isn’t in your house and you have to ask someone to get it for you while you’re cooking. In the meantime, you keep doing your job!

You may be familiar with this way of doing things — in programming languages — we refer to it as **_asynchronous._**

We often do things asynchronously in programming. That is we initiate something and before even it completes we initiate some other task.

In JavaScript, we rely a lot on asynchronous operations — whose results we don’t have yet but will at some later point.

JavaScript in itself is not asynchronous but it supports asynchronous programming.

ES6 has introduced an idea that makes handling asynchronous tasks easier: **_Promises_**.

A promise is an object — a **placeholder** for the eventual result.

It is not that we could not do the async operation before. We did!

All we had to do is to make use of Callbacks in a certain way! Doing so was a torture when we needed to do a task when our operation failed.

Promises standardized the way to deal with **_asynchronous events_ **and **_callbacks_**.

I’ve seen people struggling with promises. This post aims to assist individuals in comprehending this amazing topic. We will endeavour to gain a proper mental model of promises through real-life examples.

> The more you struggle to understand, the less you understand any problem. To understand, the mind must be quiet.
> 
> — Jiddu Krishnamurti

Since people forget things but remember stories.

## Let us understand promises with this little story

<figure class="hm hn ho hp hq hr ni nj paragraph-image">![](https://miro.medium.com/max/1000/1*WhZJwK8xvjdDGnsnlAESKg.png)</figure>

<figure class="cj hr ni nj paragraph-image">![](https://miro.medium.com/max/1000/1*co3JdR-Qq5BB1ds7CaQtog.png)</figure>

I am not yet a master storyteller! However, the preceding scenario contains all of the necessary information to help you comprehend the concepts of Promises.

## Let us take the key points from it and apply them to JavaScript World.

We need a standard description of what a Promise is — nothing better than MDN.

<figure class="hm hn ho hp hq hr ni nj paragraph-image">![](https://miro.medium.com/max/1000/1*oJVZUT9eDxjcmmxTr7tORg.png)</figure>

Let us see, how this definition relates to our story.

<figure class="hm hn ho hp hq hr ni nj paragraph-image">![](https://miro.medium.com/max/1000/1*FtNMSdpZsKwT1nIDEgSx7Q.png)</figure>

The definition makes a lot more sense now!

In JavaScript, a **_Promise_** is just an object. It is a **_placeholder_** for a value we do not have right now but will have later. It ensures that we will eventually know the result of an asynchronous operation.

## Circumstances do not matter — only your state of being matters — what state of being are you choosing?

A promise is nothing more than an object, and it is usual for objects to retain a state. By modifying the state, we do many complex tasks in programming.

A promise is always in one of the three states:

*   **pending:** which is the initial state — that is neither fulfilled nor rejected.
*   **fulfilled:** meaning that the operation was completed successfully.
*   **rejected:** meaning that the operation failed.

<figure class="hm hn ho hp hq hr cs ct paragraph-image">![](https://miro.medium.com/max/700/1*7pNnd_1UDwypRvzeYg9LKw.png)</figure>

Let us establish a strong mental model by tying the underlying _principles to our tale_ before diving into the code.

<figure class="hm hn ho hp hq hr ni nj paragraph-image">![](https://miro.medium.com/max/1000/1*JHbrtdV0UnagP1QaV1m36w.png)</figure>

# How to work with promises?

If we want to use promise in our code, then we must first understand these three fundamental concepts.

*   **How a to create Promise?**
*   **How to Fulfil or Reject a Promise?**
*   **How to Run a Callback Function — Depending on Whether the Promise Is _Resolved_ or _Rejected._**

> _“It is not the answer that enlightens, but the question.”_
> 
> — Eugene Ionesco

If you understand these three things, dealing with promises will be a breeze.

<figure class="hm hn ho hp hq hr ni nj paragraph-image">![](https://miro.medium.com/max/1000/1*t9HAhA9ehDB7D14dFAuWzg.png)</figure>

Let’s take a look at each one individually.

## **How to create a** Promise**?**

We create an instance of a promise using the [**_new_** keyword](https://miro.medium.com/max/1210/1*0wJYjMQ9uwVEYzBj89oL4A.gif) with the promise constructor function.

<figure class="hm hn ho hp hq hr cs ct paragraph-image">![](https://miro.medium.com/max/700/1*tMeVXaUM_CHpZ3sXGlFzuA.png)</figure>

## How to fulfill or reject the promise?

The promise constructor function accepts one function as its argument — let us pass in an arrow function (but we could just as easily use a function expression).

<figure class="hm hn ho hp hq hr cs ct paragraph-image">![](https://miro.medium.com/max/700/1*CC3LeEpSGKhndrshT50t8w.png)</figure>

This function is called an executor function, it automatically receives two arguments `resolve` and `reject`.

<figure class="hm hn ho hp hq hr ni nj paragraph-image">![](https://miro.medium.com/max/1000/1*v4oUtqmnkQltn1XWPe0Atw.png)</figure>

Keep in mind — **_resolve_** and **_reject_** both are functions.

*   `resolve` is a function which when called changes the status of the promise from pending to fulfilled.
*   `reject` is a function which when called changes the status of the promise from pending to rejected

It is important to keep in mind you cannot directly mutate the status of a promise — you can call the **_resolve_** function to fulfill the promise or the **_reject_** function to reject the promise.

<figure class="hm hn ho hp hq hr ni nj paragraph-image">![](https://miro.medium.com/max/1000/1*AOOd5xCR_LgcMIiuBPgSrw.png)</figure>

Both these functions are typically called after an async operation.

To keep things simple, let’s use `setTimeout()` to simulate the time it takes to search for the Tofu. We’ll assume that it takes your pal five minutes to go out and text you back.

<figure class="cj hr ph pi nj ni pj paragraph-image">![](https://miro.medium.com/max/1280/1*qf1pLyDTJvlhTqgJqoPx-g.png)</figure>

<figure class="cj hr pk pi nj ni pj paragraph-image">![](https://miro.medium.com/max/1296/1*hcCPqO_opLOi3o0dGLJMBA.png)</figure>

We refactored our code to include the `setTimeout` function.

If we get the Tofu — we will call `resolve` after five minutes, if we can not get the Tofu — we call `reject` after five minutes.

This is pretty much how you fulfill or reject a promise.

## **How to Run a Callback Function — Depending on Whether the Promise Is _Resolved_ or _Rejected_.**

The final step is to understand how to execute callback functions based on a promise’s state change. Remember that callback functions are functions that are supplied as an argument to another function.

Callback function means that we will use that function as an argument to another function.

Let us define two callback functions — `onFulfilled` and `onFailure`

<figure class="hm hn ho hp hq hr cs ct paragraph-image">![](https://miro.medium.com/max/700/1*_sWxMGiP9K-fxqAdKdX4IA.png)</figure>

`onFulfilled()` is the function to be called if **_resolve_** is called after the async operation

`onFailure()`is the function to be called if **_reject_** is called after the async operation.

Ideally, there would be more code in your callback functions but we simply log into the console and it serves the purpose.

Going back to our analogy, if we found the Tofu then our promise is fulfilled — we want to set up the table to eat. If the couldn’t find the Tofu then our promise is rejected — we have to start cooking the pasta.

<figure class="hm hn ho hp hq hr aj paragraph-image">![](https://miro.medium.com/max/6912/1*zAiwSKlhwltUZeP5xZvAGA.png)</figure>

You may be wondering how to make use of these two callback functions?

When we create a new promise using the promise constructor function the promise object gives us access to two methods — `then()` and `catch()`

We can call it using `promise.then()` and `promise.catch()`.

The important bit here is:

*   If the status of the promise changes from pending to fulfilled by calling the `resolve` function — the function that is passed to `then()` function will automatically get invoked
*   If the status of the promise changes from pending to rejected by calling the `reject` function the function that is passed to `catch()` function will automatically get invoked

<figure class="hm hn ho hp hq hr ni nj paragraph-image">![](https://miro.medium.com/max/1000/1*8KP6GnrNBaeq1bZpJLW2jw.png)</figure>

In our case, we need to pass

*   `onFulfilled` function to `then()`
*   `onFailure` function to `catch()`

Both functions are callback functions since they are supplied as arguments to other functions. I’m reminding you of this repeatedly since I’ve seen many individuals get afraid of the term “callback” — there is nothing to fear — they are just regular functions.

<figure class="hm hn ho hp hq hr cs ct paragraph-image">![](https://miro.medium.com/max/700/1*wusFSG_8gbm0dxNUYUTy8g.png)</figure>

<figure class="hm hn ho hp hq hr cs ct paragraph-image">![](https://miro.medium.com/max/700/1*fXY1VLoLsNwaRqfXsIsVpA.png)</figure>

Our promise code works as expected. But there is room for improvement!

What if we want to send out some data when **_resolving_** or **_rejecting_** a promise?

That way inside our callback functions we can make use of the value to do something else.

Well, it turns out that we can do that by passing an argument to **_resolve_** or **_reject_**,

*   for the **_resolve_** function, we’ll pass in a string that says `Got the Tofu`
*   for **_reject_** function, we will pass in a string that says `Can’t get Tofu`

<figure class="hm hn ho hp hq hr ni nj paragraph-image">![](https://miro.medium.com/max/1000/1*XYWSjSOSmiy4XuXfkeFHHA.png)</figure>

<figure class="cj hr ni nj paragraph-image">![](https://miro.medium.com/max/1000/1*6RorBrRM7TdjsBEcZTP9rw.png)</figure>

But how do we access these strings in our callback function?

Well, the great thing about a promise is that it will automatically inject the argument passed to _resolve_ as the argument to the `onFulfilled` callback and the argument passed to **_reject_** as the argument to the `onFailure` callback.

<figure class="cj hr pu pi nj ni pj paragraph-image">![](https://miro.medium.com/max/1504/1*ihtxdnipaHUONsLsjc0gyg.png)</figure>

<figure class="cj hr pv pi nj ni pj paragraph-image">![](https://miro.medium.com/max/1297/1*-s9oryvwxOitqLr-pl3lCA.png)</figure>

You can see that I’ve included parameters to both these callbacks and simply log them to the console.

We would now see the output `Got the Tofu Set up the table` when the promise is fulfilled or if there is an error and hence a rejection we would see `Can't get Tofu Cook pasta.`

<figure class="hm hn ho hp hq hr aj paragraph-image">![](https://miro.medium.com/max/2000/1*hiCMDWkdyM8C12p_YvVJhw.png)</figure>

One great example of using promises is fetching data from a server; we promise that we’ll eventually get the data, but there’s always a chance that problems will occur.

In a practical scenario, things will be different.

Your result would be:

*   an object(JSON)
*   an array,
*   or any other data type that your async operation returns.

Essentially this is pretty much is the fundamentals of promises in JavaScript. There are a few more details which we will understand in the next article.

> “A promise means everything, but once it gets broken, sorry means nothing”
> 
> — anonymous

# Summary

*   A promise is an object — a **placeholder** for the eventual result.
*   In past we used Callbacks, to perform the async operation
*   Using callback was a pain especially when you needed to do error handling.
*   Promises standardized the way to deal with asynchronous events and Callbacks.
*   A promise is always in one of three states: pending (the first), fulfilled, or rejected.
*   The operation was completed was marked as fulfilled. The operation was rejected, which means it failed.
*   We create a promise using the [**_new_** keyword](https://miro.medium.com/max/1210/1*0wJYjMQ9uwVEYzBj89oL4A.gif) with the promise constructor function.
*   You cannot directly mutate the status of a promise — you can call the **_resolve_** function to fulfill the promise or the **_reject_** function to reject the promise.
*   We learned How a Promise is created, How to Fulfil or Reject a Promise, How to Run a Callback Function — Depending on Whether the Promise Is Resolved or Rejected.

# Note of Gratitude

I wanted to take this last opportunity to say thank you.

Thank you for being here! I would not be able to do what I do withoutpeople like youwho follow along and take that leap of faith to read my post.

I hope you’ll [**join me**](https://polymathsomnath.medium.com/subscribe) in [**my future blog post**](https://polymathsomnath.medium.com/subscribe) and stick around because I think we have something great here. And I hope that I will be able to help you along in your career for many more years to come!

See you next time. Bye!