Exploring Promises: .all vs .allSettled / .race vs .any
Ler em pt/br Promises emerged in 2015, with the release of ECMAScript 6 (ES2015), to make our experience as developers less complicated when dealing with asynchronous operations. If you study or work with JavaScript, you have certainly used a Promise.all() or a Promise.race() somewhere. And to make the developer's life even easier, with the release of more recent versions of JavaScript, we had access to two new Promises methods: Promise.allSettled() and Promise.any() (ES11 and ES2021, respectively). But what is the difference between them and when should we use each? Summary Promise.all vs Promise.allSettled: focus on result Promise.race vs Promise.any: focus on speed Promise.all vs Promise.allSettled: focus on result Sometimes when you are developing an application, at a given moment you will need to execute different API calls. If these calls are independent of each other, it would be a good choice to execute all calls simultaneously, improving the application's performance, in addition to making the code more concise. Promise.all() Receives an array of Promises as an argument; Executes the operations simultaneously (in parallel); Resolves when all Promises are successfully resolved; Rejects immediately if one of the Promises fails, blocking the execution of the following Promises. async function getDataInParallel() { const [users, products] = await Promise.all([ fetch('/api/users').then(resp => resp.json()), fetch('/api/products').then(resp => resp.json()), ]); return { users, products }; } The Promise.all() is quite useful when you need to ensure that all Promises succeed and the function receives all the results it needs before executing any other action. Promise.allSettled() Also receives an array of Promises as an argument; Also executes the operations simultaneously (in parallel); Resolves when all Promises finish their execution, either successfully or failed, returning an object for each Promise containing its status (fulfilled or rejected); Never rejects and, consequently, does not block the execution of Promises. async function getFailableDataInParallel() { const results = await Promise.allSettled([ fetch('/api/users').then(resp => resp.json()), fetch('/api/products').then(resp => resp.json()), ]); // Check each result individually: const data = results.map(result => { if (result.status === 'fulfilled') { return result.value; } else { console.error(result.reason); return null; } }); return data; } The Promise.allSettled() does not block the application if any Promise fails, in addition to allowing individual treatment for each call's success or error status. It is like a status report, which waits for all requests to be resolved or rejected and allows the user to evaluate and treat each case. Back to summary Promise.race vs Promise.any: focus on speed On the other hand, Promise.race() and Promise.any() are about handling the first response in a set of asynchronous operations. Promise.race() Receives an array of Promises as arguments; Executes the operations simultaneously (in parallel); Returns the first Promise that is completed OR rejected. async function getUserData() { const timeout = new Promise((_, reject) => { setTimeout(() => reject('Timeout!'), 5000); }); try { // Use race to get the first available result const result = await Promise.race([ getFromCache, getLocalData, getFromAPI, timeout ]); return result; } catch (error) { console.log(error); // Execution stops here if there is an error } } Promise.race() is very useful when we need a fast response — the first available return, regardless of whether it is success or error. It is also often used with timeouts, as in the example above, to ensure that we get any response within a time limit and to prevent slow requests from continuing to consume resources. Promise.any() Also receives an array of Promises as arguments; Executes the operations simultaneously (in parallel); Returns the first Promise that completes successfully, ignoring rejections; Only rejects if all Promises are rejected. async function getUserData() { try { // Returns the first successful search const result = await Promise.any([ getFromCache, getLocalData, getFromAPI ]); return result; } catch (error) { console.log(error); // Only falls here if ALL fetches fail } } Promise.any() is useful when you need at least one of the requests to complete successfully, and is ideal for fallbacks and redundancies, such as loading a resource from multiple sources (CDN, local, etc.) or connecting to different servers in case of failure. Back to summary In an increasingly asynchronous digital world, understanding how to manage multiple concurrent operations in

Promises emerged in 2015, with the release of ECMAScript 6 (ES2015), to make our experience as developers less complicated when dealing with asynchronous operations.
If you study or work with JavaScript, you have certainly used a Promise.all()
or a Promise.race()
somewhere. And to make the developer's life even easier, with the release of more recent versions of JavaScript, we had access to two new Promises methods: Promise.allSettled()
and Promise.any()
(ES11 and ES2021, respectively).
But what is the difference between them and when should we use each?
Summary
Promise.all vs Promise.allSettled: focus on result
Promise.race vs Promise.any: focus on speed
Promise.all vs Promise.allSettled: focus on result
Sometimes when you are developing an application, at a given moment you will need to execute different API calls. If these calls are independent of each other, it would be a good choice to execute all calls simultaneously, improving the application's performance, in addition to making the code more concise.
Promise.all()
- Receives an array of Promises as an argument;
- Executes the operations simultaneously (in parallel);
- Resolves when all Promises are successfully resolved;
- Rejects immediately if one of the Promises fails, blocking the execution of the following Promises.
async function getDataInParallel() {
const [users, products] = await Promise.all([
fetch('/api/users').then(resp => resp.json()),
fetch('/api/products').then(resp => resp.json()),
]);
return { users, products };
}
The Promise.all() is quite useful when you need to ensure that all Promises succeed and the function receives all the results it needs before executing any other action.
Promise.allSettled()
- Also receives an array of Promises as an argument;
- Also executes the operations simultaneously (in parallel);
- Resolves when all Promises finish their execution, either successfully or failed, returning an object for each Promise containing its status (
fulfilled
orrejected
); - Never rejects and, consequently, does not block the execution of Promises.
async function getFailableDataInParallel() {
const results = await Promise.allSettled([
fetch('/api/users').then(resp => resp.json()),
fetch('/api/products').then(resp => resp.json()),
]);
// Check each result individually:
const data = results.map(result => {
if (result.status === 'fulfilled') {
return result.value;
} else {
console.error(result.reason);
return null;
}
});
return data;
}
The Promise.allSettled() does not block the application if any Promise fails, in addition to allowing individual treatment for each call's success or error status. It is like a status report, which waits for all requests to be resolved or rejected and allows the user to evaluate and treat each case.
Back to summary
Promise.race vs Promise.any: focus on speed
On the other hand, Promise.race()
and Promise.any()
are about handling the first response in a set of asynchronous operations.
Promise.race()
- Receives an array of Promises as arguments;
- Executes the operations simultaneously (in parallel);
- Returns the first Promise that is completed OR rejected.
async function getUserData() {
const timeout = new Promise((_, reject) => {
setTimeout(() => reject('Timeout!'), 5000);
});
try {
// Use race to get the first available result
const result = await Promise.race([
getFromCache,
getLocalData,
getFromAPI,
timeout
]);
return result;
} catch (error) {
console.log(error);
// Execution stops here if there is an error
}
}
Promise.race() is very useful when we need a fast response — the first available return, regardless of whether it is success or error. It is also often used with timeouts, as in the example above, to ensure that we get any response within a time limit and to prevent slow requests from continuing to consume resources.
Promise.any()
- Also receives an array of Promises as arguments;
- Executes the operations simultaneously (in parallel);
- Returns the first Promise that completes successfully, ignoring rejections;
- Only rejects if all Promises are rejected.
async function getUserData() {
try {
// Returns the first successful search
const result = await Promise.any([
getFromCache,
getLocalData,
getFromAPI
]);
return result;
} catch (error) {
console.log(error); // Only falls here if ALL fetches fail
}
}
Promise.any() is useful when you need at least one of the requests to complete successfully, and is ideal for fallbacks and redundancies, such as loading a resource from multiple sources (CDN, local, etc.) or connecting to different servers in case of failure.
Back to summary
In an increasingly asynchronous digital world, understanding how to manage multiple concurrent operations in JavaScript has become an essential skill for developers. In this article, we explore some important Promises methods with examples, showing how each of them works and, more importantly, when and why you should choose one over the other.
Until next time (and I promise I'll be back soon)!