Introduction:
JavaScript Promises have become a fundamental part of modern web development, allowing developers to write asynchronous code in a more readable and maintainable way. One of the recent additions to the Promise API is the Promise.allSettled
method, which returns a promise that resolves after all of the given promises have either resolved or rejected, with an array of objects that each describes the outcome of each promise. In this blog post, we will explore how to polyfill Promise.allSettled
for environments that do not yet support it, which can be a valuable skill for those preparing for technical interviews.
Understanding Promise.allSettled:
Before we dive into the polyfill implementation, let's first understand the behavior of Promise.allSettled
. Unlike Promise.all
, which short-circuits and rejects immediately if any of the input promises reject, Promise.allSettled
waits for all promises to settle (either resolve or reject) and then returns a promise that resolves with an array of result objects. Each result object has a status
property that indicates whether the promise was fulfilled ('fulfilled'
) or rejected ('rejected'
), and a value
or reason
property containing the fulfillment value or rejection reason, respectively
Implementing the Polyfill:
Check for Existing Implementation:
- Before polyfilling, we check if
Promise.allSettled
already exists. If it does, we do not override it.
- Before polyfilling, we check if
Polyfill Definition:
We define
Promise.allSettled
as a function that takes an array of promises as its input.It returns a new promise created by calling
Promise.all
.Inside
Promise.all
, we map over each promise in the input array.
Mapping Promises:
For each promise, we call
.then
to handle the fulfillment and rejection cases separately.If the promise fulfills, we return an object with
status: 'fulfilled'
andvalue: <fulfillment value>
.If the promise rejects, we return an object with
status: 'rejected'
andreason: <rejection reason>
.
Returning Mapped Promises:
The
map
method returns an array of mapped promises (each mapping to a promise that resolves with an object describing its outcome).This array of promises is passed to
Promise.all
, which waits for all promises to settle (either resolve or reject).
Final Result:
- The final result of
Promise.allSettled
is a promise that resolves with an array of result objects, where each object describes the outcome of the corresponding input promise.
- The final result of
if (!Promise.allSettled) {
Promise.allSettled = function (promises) {
return Promise.all(
promises.map(promise =>
promise.then(
value => ({
status: 'fulfilled',
value
}),
reason => ({
status: 'rejected',
reason
})
)
)
);
};
}
Test cases
Promise.allSettled([])
.then(results => {
console.log(results);
});
// resolves []
const mixedPromises = [
Promise.resolve('Fulfilled'),
Promise.reject('Rejected'),
Promise.resolve('Another Fulfilled'),
Promise.reject('Another Rejected')
];
Promise.allSettled(mixedPromises)
.then(results => {
console.log(results);
});
// output
/*
[
{ status: 'fulfilled', value: 'Fulfilled' },
{ status: 'rejected', reason: 'Rejected' },
{ status: 'fulfilled', value: 'Another Fulfilled' },
{ status: 'rejected', reason: 'Another Rejected' }
]
*/