Synchronizing Asynchronous Call with Promise.all()

Before discussing Promise.all(), let's first talk about what a Promise is in JavaScript. In short, a Promise is a way to handle asynchronous operations in JavaScript in a simple manner. A Promise has three states: immediately after invoking a Promise call, it goes into the pending state. If the Promise is fulfilled successfully, then it is resolved.

However, if it cannot get the results, it will automatically fall into the rejected state. There is another type of Promise, called "Promise.all()", which can take multiple Promises and return the result based on the given Promises. Today, we will discuss Promise.all() in detail, including examples, syntax, and use cases. Let's begin.

Table of Contents

  1. What is Promise.all()
  2. How to use Promise.all()
  3. When to Promise.all()

What is Promise.all()

Promise.all() is a built-in helper function in JavaScript that takes an array of Promises and returns a Promise. The question is, what will be the result of a new Promise? Promise.all() works in an interesting way: it only goes to resolve state when all of the Promises inside Promise.all() are resolved.

However, it immediately throws a rejected state after encountering the first rejected state of any Promise.

We can implement Promise.all() in many ways. Like we can use try/catch or .then.   Please see the below syntax for reference

Promise.all([promiseOne, promiseTwo, promiseThree])  // takes all of the promise in a array
  .then((resolve) => console.log(resolve)) // gives the results of the resolved promise
  .catch((error) => console.log(error));  // gives the first rejected promise immediately

How to use Promise.all()

Now it's time for a complete example of how we can use Promise.all() with both the resolve and reject states. In example 1, we have two Promises. For reference, we resolved promiseOne after 1 second and promiseTwo after 2 seconds. As both of them are resolved, we got the resolved data in Promise.all().

Example 1:

In this example, we use two Promises, promiseOne and promiseTwo. Both promises are resolved after 1 and 2 seconds, respectively. We pass both Promises to Promise.all(), which returns a new Promise. Since both Promises are resolved successfully, the then() method is called, and we log the result to the console.

const promiseOne = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("promiseOne resolved ");
    console.log("Shouts.dev is found on the internet");
  }, 1000);
});

const promiseTwo = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("promiseTwo resolved ");
    console.log("Yes, Shouts.dev is Programming Blog Site");
  }, 2000);
});

Promise.all([promiseOne, promiseTwo])
  .then((resolve) => console.log("resolved data ->", resolve)) //resolved data -> [ 'promiseOne resolved', 'promiseTwo resolved'] 
  .catch((error) => console.log("error message ->", error));

Now it's time for a complete example of how we can use Promise.all() with both the resolve and reject states. In example 1, we have two Promises. For reference, we resolved promiseOne after 1 second and promiseTwo after 2 seconds. As both of them are resolved, we got the resolved data in Promise.all().

Example 1:

But In example 2, promiseOne is resolved after 1 seconds, but promiseTwo is rejected after 5 seconds. Because of this rejection, Promise.all() throws the promiseTwo error immediately. The same thing happens if we have hundreds of Promises, and one Promise with a reject state will invoke the error.

Example 2:

const promiseOne = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('promiseOne resolved successfully');
    console.log("Shouts.dev is found on the internet");
  }, 1000);
});


const promiseTwo = new Promise((resolve, reject) => {
  setTimeout(() => {
      reject("promiseTwo rejected");
    console.log("data not found");
  },  5000);
});


Promise.all([promiseOne, promiseTwo])
  .then((resolve) => console.log(resolve))
  .catch((error) => console.log('error message ->', error)) // error message -> promiseTwo rejected 

When to Promise.all()

Now, let's consider a scenario where you have to make multiple API calls from different servers, and based on the responses, you want to render a component. In this scenario, you can take advantage of Promise.all() and combine multiple API calls into one single API call.

Similarly, you can wait for multiple asynchronous tasks to complete before moving on to the next step in a process, making them easier to handle and chain together with other operations. This way, we can synchronize multiple asynchronous function calls.