Promise.allSettled – Keeping All Promises in View
In modern JavaScript applications, it is common practice to execute multiple asynchronous operations simultaneously – such as loading data from different APIs, uploading multiple files, or retrieving different configuration values. Often you want to wait until all these operations are completed to then make a decision or update a display status in the UI. This is where Promise.allSettled() comes into play.
What is Promise.allSettled()?
Promise.allSettled() was introduced with ES2020 and gives you a convenient way to keep track of the outcome of multiple Promises simultaneously. Unlike Promise.all(), which aborts at the first error, Promise.allSettled() always delivers a result when all passed Promises have either been fulfilled or rejected.
The return value of Promise.allSettled() is a Promise that is fulfilled as soon as all Promises have been processed. The result is an array of objects, where each object has two properties:
- status:
'fulfilled'or'rejected' - value: The value if the Promise was fulfilled
- reason: The error reason if the Promise was rejected
A classic example:
const promise1 = Promise.resolve('Data from Server A');
const promise2 = Promise.resolve('Data from Server B');
const promise3 = Promise.reject('Error fetching from Server C');
Promise.allSettled([promise1, promise2, promise3])
.then(results => {
console.log(results);
// [
// { status: 'fulfilled', value: 'Data from Server A' },
// { status: 'fulfilled', value: 'Data from Server B' },
// { status: 'rejected', reason: 'Error fetching from Server C' }
// ]
// You can see: Even if one operation fails, you still get
// the results of all other Promises. This allows you to specifically react to partial errors.
});
Difference from Promise.all()
Promise.all()aborts on the first rejection and immediately returns the error. This is useful when all operations must succeed.Promise.allSettled()waits for all Promises to complete, regardless of whether they were fulfilled or rejected. This is useful when you want to know the outcome of each individual operation.
Comparison:
// With Promise.all()
Promise.all([promise1, promise2, promise3])
.then(results => {
// Only reached if ALL Promises were fulfilled
console.log('All succeeded:', results);
})
.catch(error => {
// Immediately entered on the first error
console.error('At least one failed:', error);
});
// With Promise.allSettled()
Promise.allSettled([promise1, promise2, promise3])
.then(results => {
// ALWAYS reached when all Promises are completed
const successful = results.filter(r => r.status === 'fulfilled');
const failed = results.filter(r => r.status === 'rejected');
console.log(`${successful.length} successful, ${failed.length} failed`);
});
Practical Use Cases
1. Multiple API Calls:
async function fetchAllData() {
const endpoints = [
'/api/users',
'/api/posts',
'/api/comments'
];
const promises = endpoints.map(url => fetch(url).then(r => r.json()));
const results = await Promise.allSettled(promises);
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`${endpoints[index]}: Success`, result.value);
} else {
console.error(`${endpoints[index]}: Failed`, result.reason);
}
});
}
2. File Upload:
async function uploadFiles(files) {
const uploadPromises = files.map(file => uploadFile(file));
const results = await Promise.allSettled(uploadPromises);
const successful = results.filter(r => r.status === 'fulfilled').length;
const failed = results.filter(r => r.status === 'rejected').length;
return {
message: `${successful} of ${files.length} files uploaded successfully`,
failed: failed,
details: results
};
}
3. Validation of Multiple Inputs:
async function validateForm(formData) {
const validations = [
validateEmail(formData.email),
validatePhone(formData.phone),
validateAddress(formData.address)
];
const results = await Promise.allSettled(validations);
const errors = results
.filter(r => r.status === 'rejected')
.map(r => r.reason);
return {
valid: errors.length === 0,
errors: errors
};
}
Conclusion
Promise.allSettled() is a valuable tool when you need to execute multiple asynchronous operations and want to know the outcome of each individual operation – regardless of whether they were successful or not. It enables robust error handling and gives you full control over the results of all Promises.
Use Promise.allSettled() in your next project and experience how it simplifies working with multiple asynchronous operations!