[JavaScript] Understanding Promise Object

Promise Object, asynchronous JavaScript, then(), catch(), async/await

[JavaScript] Understanding Promise Object

Introduction

In this article, we will talk about:

  1. What is Promise Object?

  2. Why do we use it?

  3. Promise.all() vs Promise.allSettled()

  4. Converting async/await to promise object


Promise Object

Promise object in JavaScript is used for asynchronous communication. Asynchronous communication refers to functions running in parallel with other functions. If you want to find out more about asynchronous JavaScript and synchronous JavaScript, you can have a look at this article:

Asynchronous vs Synchronous JavaScript

Promise object "promises" that the response will be sent and evaluated. The processing looks like this:

The response will be either fulfilled or rejected.

If the response is successful, we can use the resolve() method and send the data to the then() method.

If the response is rejected, we can use the reject() method and send the error code or error to the catch() method. I will demonstrate how to do it later on.


Why Do We Need Promise?

Promise Object allows developers to store the response and evaluate that response whenever they want. For callback() functions, you cannot do it. So, having the option to use it anytime is quite huge.


Using Promise

Declaring promise object:

const promise = new Promise((resolve, reject) => {
    // your code
});

Evaluating:

promise.then((resolve) => {
    // your code
}).catch((error) => {
    // your code
});

As I mentioned earlier, you can use the promise anytime you want. In this example, I stored the response in the variable(promise) and evaluated it later.

.then() is to evaluate the fulfilled responses.

.catch() is to evaluate the rejected responses (errors).

catch() can be placed in the middle:

const promise = new Promise((resolve, reject) => {});
promise.then((resolve) => {
    // your code
}).catch((reject) => {
    // your code
}).then((resolve) => {
    // your code
});

If you are not sure if the error will occur in the first then() method, you can place the catch() right after that, so you can prevent the error. Then, you may proceed by writing another then().

Using the then() or catch() method several times (just like the example above) is called promise chaining.


Promise.all() vs Promise.allSettled()

The answer for this section is, you will use Promise.allSettled() for most of the time due to the problems with the Promise.all().

How to use:

const p1 = axios.get("your_url");
const p2 = axios.get("your_url");
const p3 = axios.get("your_url");
const p4 = axios.get("your_url");
const p5 = axios.get("your_url");
const promises = [p1, p2, p3, p4, p5];

Promise.all(promises)
.then((resolve) => {
    // your code
.catch((error) => {
    // your code
});

Promise.allSettled(promises)
.then((resolve) => {
    // your code
.catch((error) => {
    // your code
});

The problem with the Promise.all() is, if there is at least one error among p1 - p5, it will immediately go to that catch() method. This means if p2 is an error, p1, p3, p4 and p5 will go to the catch() although they are fulfilled.

Promise.allSettled() solves the problem. The function returns an array that stores the results (either fulfilled or rejected).

Example for Promise.allSettled():

const promise1 = Promise.resolve(1); // fulfilled
const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(10); // rejected
    }, 3000);
});
const promises = [promise1, promise2]; // stores responses

Promise.allSettled(promises) // evaluate responses
.then((resolve) => {
    console.log(resolve);
})


Converting async/await to Promise

You may come across a situation when you have to change async/await to promise. I learned this conversion from a Korean YouTuber, so I will leave the reference here:

https://www.youtube.com/watch?v=1DGAyl4kxhY&list=PLcqDmjxt30Rt9wmSlw1u6sBYr-aZmpNB3&index=14

At first, learning how to make conversions might be difficult, but you will get the idea of it as you read the code over and over.

Async/await code:

async function asyncFunc() {
    console.log("Synchronous JS here");
    const a = await 1; // 1 is still considered synchronous.
    console.log("dummy text");
    await null;
    const b = await Promise.resolve(1);
    console.log("dummy text2");
}

When you read the async/await function, you need to read from right to left instead of reading from left to right.

console.log("Synchronous JS here"); and const a = await 1; are still synchronous JS but when we meet the await keyword, then it becomes asynchronous JS.

Each await keyword is the same as then(). There are three(3) await right, so we will need to have three then() methods.

  1. Three then():
asyncFunc()
.then(() => {

})
.then(() => {

})
.then(() => {

});
  1. Key in the variables
asyncFunc()
.then((a) => {

})
.then(() => {

})
.then((b) => {

});
  1. Put the rest
asyncFunc()
.then((a) => {
    // anything between the first and the next await keyword comes here.
    // make sure that you read from right to left.
    console.log("dummy text");
    return null;
})
.then(() => {
    // anything between the second and the next await keyword comes here.
    return Promise.resolve(1);
})
.then((b) => {
    console.log("dummy text2");
});

reference: https://www.w3schools.com/js/js_asynchronous.asp

Did you find this article valuable?

Support Jay's Dev Blog by becoming a sponsor. Any amount is appreciated!