Handling Multiple Promises Like a Pro: Promise.all, Promise.allSettled, Promise.any, Promise.race

Handling Multiple Promises Like a Pro: Promise.all, Promise.allSettled, Promise.any, Promise.race

Static Promise Methods

·

4 min read

Prerequisites

It is important to have a solid understanding of Promises and Promise() constructor in JavaScript before diving into static promise methods. If you are new to Promises or if you need a refresher I will suggest you to read this article before proceeding.

So are you ready to take your Promise skills to the next level? Let's dive in!"


Shared Characteristics

In this section, I want to highlight some commonalities between all four methods.

  • Promise.all(), Promise.allSettled(), Promise.any() and Promise.race() - these are the static methods that are available on the Promise() constructor.

  • We can use any of these methods to handle multiple promises simultaneously depending on our requirements.

  • All of these methods take an Array of Promise objects as input and return a single Promise Object.

So that were all the common points between these methods, In the subsequent sections we will see each of the methods in action, I would highly suggest you to go through the code snippets along with reading about the methods, feel free to paste them on your code editors and play around with it. I am confident that it will give you clarity on when to use which method.


Promise.all()

  • The promise object returned by Promise.all() will be fulfilled when all the promises in the array are fulfilled. i.e. then() block will be executed when all of the promises are fulfilled.

  • then() block will receive an array of fulfillment values in the data argument.

  • If any of the promises in the array is rejected, the promise returned by Promise.all() will also be rejected. i.e. the catch() block will be executed with the error of the first rejected promise.

Promise.all([makePayment(), placeOrder(), updateStore()])
  .then((data) => console.log(data))
  .catch((error) => console.log(error));

function makePayment() {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 1000, "Payment Successful");
  });
}

function placeOrder() {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 1500, "Order Placed");
  });
}

function updateStore() {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 3000, "Store Updated");
  });
}

Promise.allSettled()

  • The resulting promise from Promise.allSettled() will be fulfilled once all of the promises in the array are rejected or resolved.

  • So we can conclude that we don't need to attach a catch() method to it, then() block will be executed always.

  • then() block will receive an array of Objects in the data argument.

  • This is how the objects in the array will look like.

Promise.allSettled([getUsername(), getRelationshipStatus()]).then((data) =>
  console.log(data)
);

function getUsername() {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 1000, "Ashutosh Raturi");
  });
}

function getRelationshipStatus() {
  return new Promise((resolve, reject) => {
    setTimeout(reject, 1500, new Error("Failed to fetch relationship status!"));
  });
}

Promise.any()

  • The returned promise from Promise.any() will be fulfilled if any of the Promise in the array is fulfilled.

  • then() block will be executed as soon as the first promise is fulfilled and data argument will receive the fulfillment value from the first resolved promise.

  • The returned promise from Promise.any() will be rejected only if all the promises in the array are rejected. So in this case catch() block will be executed with the error AggregateError: All promises were rejected.

Promise.any([authenticateFromGoogle(), authenticateFromFacebook()])
  .then((data) => console.log(data))
  .catch((error) => console.log(error));

function authenticateFromGoogle() {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 1000, "User authenticated successfully");
  });
}

function authenticateFromFacebook() {
  return new Promise((resolve, reject) => {
    setTimeout(reject, 1500, new Error("Authentication Failed!"));
  });
}

Promise.race()

The resulting Promise from Promise.race() will be fulfilled or rejected depending upon the status of the first settled promise. i.e. whatever will be the status of the first settling promise will be status of returned promise from Promise.race().

const validity = "valid";

Promise.race([checkvalidityFromSourceA(), checkValidityFromSourceB()])
  .then((data) => console.log(data))
  .catch((error) => console.log(error));

function checkvalidityFromSourceA() {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 1000, validity + " From Source A");
  });
}

function checkValidityFromSourceB() {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 1500, validity + " From Source B");
  });

Conclusion

So that was all from my side on static methods to handle multiple promises. I hope this will give you the confidence to handle promises like a boss. To read more on this please visit MDN web docs. Please feel free to write down your thoughts and feedback on this article. Thank you :)