Understanding the Promise API in JavaScript
The Promise API in JavaScript provides methods to handle multiple promises concurrently. These methods—Promise.all()
, Promise.allSettled()
, Promise.race()
, and Promise.any()
—are powerful tools for managing asynchronous operations. Let’s explore each in detail.
1. Promise.all()
The Promise.all()
method takes an iterable (e.g., an array) of promises and returns a single promise that:
Resolves when all the promises in the array have resolved.
Rejects if any of the promises in the array reject, returning the reason for the first rejected promise.
Use Case
Use Promise.all()
when you need all promises to succeed, and their results can be used collectively.
Syntax
Promise.all([promise1, promise2, ...])
.then(results => {
// All promises resolved
console.log(results);
})
.catch(error => {
// At least one promise rejected
console.error(error);
});
Example
const promise1 = Promise.resolve(10);
const promise2 = Promise.resolve(20);
const promise3 = Promise.resolve(30);
Promise.all([promise1, promise2, promise3])
.then(results => console.log(results)) // Output: [10, 20, 30]
.catch(error => console.error(error));
const failingPromise = Promise.reject("Error!");
Promise.all([promise1, failingPromise])
.then(results => console.log(results))
.catch(error => console.error(error)); // Output: Error!
2. Promise.allSettled()
The Promise.allSettled()
method takes an iterable of promises and returns a single promise that:
Resolves when all promises settle (i.e., resolve or reject).
Provides an array of objects, each describing the outcome of each promise (
status
andvalue
orreason
).
Use Case
Use Promise.allSettled()
when you need to know the outcome of all promises, regardless of whether they resolve or reject.
Syntax
Promise.allSettled([promise1, promise2, ...])
.then(results => {
console.log(results);
});
Example
const promise1 = Promise.resolve(10);
const promise2 = Promise.reject("Error!");
const promise3 = Promise.resolve(30);
Promise.allSettled([promise1, promise2, promise3])
.then(results => console.log(results));
/*
Output:
[
{ status: 'fulfilled', value: 10 },
{ status: 'rejected', reason: 'Error!' },
{ status: 'fulfilled', value: 30 }
]
*/
3. Promise.race()
The Promise.race()
method takes an iterable of promises and returns a single promise that:
- Settles (resolves or rejects) as soon as the first promise settles (whichever happens first).
Use Case
Use Promise.race()
when you are interested in the fastest promise, regardless of whether it resolves or rejects.
Syntax
Promise.race([promise1, promise2, ...])
.then(result => {
// First promise to settle
console.log(result);
})
.catch(error => {
console.error(error);
});
Example
const promise1 = new Promise(resolve => setTimeout(() => resolve("First!"), 100));
const promise2 = new Promise(resolve => setTimeout(() => resolve("Second!"), 200));
Promise.race([promise1, promise2])
.then(result => console.log(result)) // Output: "First!"
.catch(error => console.error(error));
const failingPromise = new Promise((_, reject) => setTimeout(() => reject("Error!"), 50));
Promise.race([failingPromise, promise1])
.then(result => console.log(result))
.catch(error => console.error(error)); // Output: "Error!"
4. Promise.any()
The Promise.any()
method takes an iterable of promises and returns a single promise that:
Resolves as soon as the first promise resolves.
Rejects only if all promises reject, with an
AggregateError
containing the rejection reasons.
Use Case
Use Promise.any()
when you need the first successful result and can ignore failures.
Syntax
Promise.any([promise1, promise2, ...])
.then(result => {
console.log(result);
})
.catch(error => {
console.error(error);
});
Example
const promise1 = Promise.reject("Error 1");
const promise2 = Promise.reject("Error 2");
const promise3 = Promise.resolve(30);
Promise.any([promise1, promise2, promise3])
.then(result => console.log(result)) // Output: 30
.catch(error => console.error(error));
const allFailing = [Promise.reject("Error A"), Promise.reject("Error B")];
Promise.any(allFailing)
.then(result => console.log(result))
.catch(error => console.error(error));
/*
Output: AggregateError: All promises were rejected
*/
Comparison of Promise Methods
Method | When Does It Resolve? | When Does It Reject? | Use Case |
Promise.all() | When all promises resolve | If any promise rejects | Wait for all promises to resolve successfully |
Promise.allSettled() | When all promises settle | Never | Get the outcome (fulfilled/rejected) of all promises |
Promise.race() | As soon as the first promise settles | If the first settled promise rejects | Use the result of the first promise to settle, regardless of resolution or rejection |
Promise.any() | As soon as the first promise resolves | If all promises reject | Return the first successful result; ignore rejections |
Conclusion
Understanding the Promise API is crucial for handling asynchronous operations in JavaScript effectively. Each method serves a specific purpose:
Use
Promise.all()
for aggregating results when all promises succeed.Use
Promise.allSettled()
for handling both successes and failures collectively.Use
Promise.race()
to act on the fastest promise.Use
Promise.any()
to retrieve the first successful promise while ignoring rejections.
Master these methods, and you’ll be well-equipped to manage complex async tasks in your projects! 🚀