Promise.all, Promise.race, Promise.allSettled, Promise.any
Promise Static Methods
JavaScript provides four main static methods for working with multiple promises simultaneously:
Promise.all()Promise.race()Promise.allSettled()Promise.any()
Each solves different tasks. Let's examine them in detail.
Promise.all()
Waits for all promises to fulfill. If at least one is rejected — the entire result is rejected.
Syntax
Promise.all(iterable)
Behavior
- ✅ Returns array of results if all promises are fulfilled successfully
- ❌ Rejects with error of the first rejected promise
- Order of results corresponds to order of promises
Successful Execution 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); // [10, 20, 30]
});
Rejection Example
const promise1 = Promise.resolve(10);
const promise2 = Promise.reject('Error!');
const promise3 = Promise.resolve(30);
Promise.all([promise1, promise2, promise3])
.then(results => {
console.log(results);
})
.catch(error => {
console.log(error); // "Error!"
// promise3 will be ignored
});
When to use?
- Loading multiple independent resources simultaneously
- All requests are required to continue work
- Need to wait for all operations to complete
async function loadUserData(userId) {
const [user, posts, comments] = await Promise.all([
fetchUser(userId),
fetchPosts(userId),
fetchComments(userId)
]);
return { user, posts, comments };
}
Important:
If one promise rejects, other promises continue executing, but their results will be ignored.
Promise.race()
Returns the result of the first settled promise (successfully or with error).
Syntax
Promise.race(iterable)
Behavior
- Completes as soon as any promise settles
- Returns result or error of the first settled promise
- Other promises are ignored
Example
const slow = new Promise(resolve => {
setTimeout(() => resolve('Slow'), 2000);
});
const fast = new Promise(resolve => {
setTimeout(() => resolve('Fast'), 500);
});
Promise.race([slow, fast])
.then(result => {
console.log(result); // "Fast"
});
Error Example
const success = new Promise(resolve => {
setTimeout(() => resolve('Success'), 2000);
});
const failure = new Promise((resolve, reject) => {
setTimeout(() => reject('Error'), 500);
});
Promise.race([success, failure])
.then(result => console.log(result))
.catch(error => console.log(error)); // "Error"
When to use?
- Timeouts: cancel operation if it takes too long
- Fallbacks: try multiple data sources
- Request racing: use the fastest response
// Request timeout
function fetchWithTimeout(url, timeout = 5000) {
return Promise.race([
fetch(url),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), timeout)
)
]);
}
fetchWithTimeout('/api/data', 3000)
.then(response => response.json())
.catch(error => console.error(error));
Promise.allSettled()
Waits for all promises to settle (successfully or with error) and returns their statuses.
Syntax
Promise.allSettled(iterable)
Behavior
- ✅ Always resolves (never rejects)
- Returns array of objects with results of each promise
- Each object contains
statusandvalue/reason
Result Format
[
{ status: 'fulfilled', value: result },
{ status: 'rejected', reason: error }
]
Example
const promises = [
Promise.resolve(10),
Promise.reject('Error'),
Promise.resolve(30)
];
Promise.allSettled(promises)
.then(results => {
console.log(results);
/*
[
{ status: 'fulfilled', value: 10 },
{ status: 'rejected', reason: 'Error' },
{ status: 'fulfilled', value: 30 }
]
*/
});
Processing Results
const results = await Promise.allSettled([
fetch('/api/users'),
fetch('/api/posts'),
fetch('/api/comments')
]);
const successful = results
.filter(r => r.status === 'fulfilled')
.map(r => r.value);
const failed = results
.filter(r => r.status === 'rejected')
.map(r => r.reason);
console.log('Successful:', successful.length);
console.log('Failed:', failed.length);
When to use?
- Need results of all operations, even if some failed
- Data aggregation from multiple sources
- Partial data loading (show what loaded)
async function loadDashboard() {
const [userResult, statsResult, notificationsResult] = await Promise.allSettled([
fetchUser(),
fetchStats(),
fetchNotifications()
]);
return {
user: userResult.status === 'fulfilled' ? userResult.value : null,
stats: statsResult.status === 'fulfilled' ? statsResult.value : null,
notifications: notificationsResult.status === 'fulfilled'
? notificationsResult.value
: []
};
}
ES2020:
Promise.allSettled() was added in ES2020 and is supported by all modern browsers.
Promise.any()
Returns the first successfully fulfilled promise. Rejects only if all promises are rejected.
Syntax
Promise.any(iterable)
Behavior
- ✅ Resolves with result of first successful promise
- ❌ Rejects only if all promises are rejected (with
AggregateError) - Ignores rejected promises as long as there's at least one successful
Example
const promises = [
Promise.reject('Error 1'),
Promise.resolve('Success!'),
Promise.reject('Error 2')
];
Promise.any(promises)
.then(result => {
console.log(result); // "Success!"
});
Complete Rejection Example
const promises = [
Promise.reject('Error 1'),
Promise.reject('Error 2'),
Promise.reject('Error 3')
];
Promise.any(promises)
.catch(error => {
console.log(error); // AggregateError: All promises were rejected
console.log(error.errors); // ['Error 1', 'Error 2', 'Error 3']
});
When to use?
- Fallbacks: try multiple data sources
- Need at least one successful result
- Working with unreliable APIs (try multiple servers)
// Load image from backup servers
async function loadImage(imageName) {
const servers = [
`https://cdn1.example.com/${imageName}`,
`https://cdn2.example.com/${imageName}`,
`https://cdn3.example.com/${imageName}`
];
try {
const imageUrl = await Promise.any(
servers.map(url => fetch(url).then(r => {
if (!r.ok) throw new Error('Failed');
return url;
}))
);
return imageUrl;
} catch (error) {
console.error('All servers unavailable');
}
}
ES2021:
Promise.any() was added in ES2021.
Comparison Table
| Method | Settles when | Success result | Error result |
|---|---|---|---|
Promise.all | All fulfilled OR first rejected | Array of all results | First error |
Promise.race | First settled | First result | First error |
Promise.allSettled | All settled | Array of {status, value/reason} | Never rejects |
Promise.any | First fulfilled OR all rejected | First successful result | AggregateError |
Practical Examples
Loading with Timeout and Retry
async function fetchWithRetry(url, retries = 3, timeout = 5000) {
for (let i = 0; i < retries; i++) {
try {
const result = await Promise.race([
fetch(url),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), timeout)
)
]);
return result;
} catch (error) {
if (i === retries - 1) throw error;
console.log(`Attempt ${i + 1} failed, retrying...`);
}
}
}
Parallel Loading with Limit
async function fetchWithLimit(urls, limit = 3) {
const results = [];
const executing = [];
for (const url of urls) {
const promise = fetch(url).then(r => r.json());
results.push(promise);
if (limit <= urls.length) {
const executing_promise = promise.then(() =>
executing.splice(executing.indexOf(executing_promise), 1)
);
executing.push(executing_promise);
if (executing.length >= limit) {
await Promise.race(executing);
}
}
}
return Promise.all(results);
}
Partial Data Loading
async function loadPageData() {
const results = await Promise.allSettled([
fetchCriticalData(), // Required data
fetchOptionalWidget1(), // Optional widgets
fetchOptionalWidget2(),
fetchOptionalWidget3()
]);
// If critical data didn't load - show error
if (results[0].status === 'rejected') {
throw new Error('Failed to load page');
}
return {
critical: results[0].value,
widgets: results.slice(1)
.filter(r => r.status === 'fulfilled')
.map(r => r.value)
};
}
Conclusion
Promise.all()— all or nothing (parallel loading of required data)Promise.race()— first wins (timeouts, request racing)Promise.allSettled()— result of each (partial loading, aggregation)Promise.any()— first successful (backup servers, fallback)
In Interviews:
Common questions:
- What's the difference between
Promise.allandPromise.allSettled? - When to use
Promise.racevsPromise.any? - What happens if you pass an empty array to each method?
- How to handle partial errors when loading data?