Multiple Promises Handling in JavaScript
Promises are a powerful way to handle asynchronous operations in JavaScript. They allow us to write clean and readable code, without using callbacks or nested functions.
However, sometimes we need to deal with multiple promises at the same time, and handle their results or errors in different ways.
For example, we might want to:
- Wait for all promises to resolve, and get an array of their values.
- Wait for all promises to settle, and get an array of their statuses and values or reasons.
- Wait for the first promise to resolve, and get its value.
Fortunately, JavaScript provides us with three static methods on the Promise constructor that can help us achieve these goals: Promise.all()
, Promise.allSettled()
and Promise.any()
.
In this article, we will explore how these methods work, what are their differences, and how to use them in various scenarios.
Promise.all()
Promise.all() takes an iterable (such as an array) of promises as an argument, and returns a single promise that resolves to an array of the values of the input promises, in the same order as they were passed. Promise.all() is useful when we need to perform multiple independent tasks that depend on each other’s results, or when we need to aggregate the results of multiple promises.
const promises = [promise1, promise2, promise3];
Promise.all(promises)
.then(results => {
// All promises fulfilled
console.log(results);
})
.catch(error => {
// At least one promise rejected
console.error(error);
});
However, Promise.all() has a drawback: it rejects as soon as any of the input promises rejects, with the reason of the first rejection. This means that if one of the promises fails, we lose access to the results of the other promises, and we cannot handle the errors individually. For example, if we have an array of promises that fetch data from different APIs, and one of them fails, we will not be able to display the data from the other APIs.
Promise.allSettled()
Promise.allSettled() is similar to Promise.all(), but it has a different behavior:
- It always resolves, regardless of whether any of the input promises rejects or not.
- It also returns a single promise that resolves to an array of objects, each describing the outcome of one of the input promises.
- In the same order as they were passed.
Each object has a status property, which can be either “fulfilled” or “rejected”, and a value property (if the promise was fulfilled) or a reason property (if the promise was rejected).
const promises = [promise1, promise2, promise3];
Promise.allSettled(promises)
.then(results => {
// Array of objects containing the status of each promise
console.log(results);
});
Promise.allSettled() is useful when we need to know the final state of each promise, regardless of whether they succeeded or failed. For example, we might want to log the results of multiple promises, or display a message for each promise based on its status.