Suggest an editImprove this articleRefine the answer for “What is the difference between promise.all and promise.allsettled?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Promise.all** rejects immediately when any promise rejects. **Promise.allSettled** always resolves, returning `{status, value/reason}` for every promise. ```js Promise.all([p1, rejectingP]).catch(err => ...); // rejects on first failure Promise.allSettled([p1, rejectingP]).then(results => ...); // always resolves ``` **Key point:** use `all` when every result is required; use `allSettled` when partial results are acceptable.Shown above the full answer for quick recall.Answer (EN)Image**Promise.all** rejects the moment any promise in the array rejects. **Promise.allSettled** always resolves, collecting a result from every promise regardless of whether it succeeded or failed. ## Theory ### TL;DR - `Promise.all` is like a restaurant order for the whole table: one dish gets cancelled, the entire order is cancelled. `Promise.allSettled` tracks each dish separately. - `Promise.all` short-circuits on the first rejection and discards the rest. - `Promise.allSettled` always resolves with `[{status, value}, {status, reason}, ...]`. - Need every result before moving on? Use `all`. Need to track all outcomes no matter what? Use `allSettled`. - Both preserve input order, not settle order. ### Quick example ```javascript const p1 = Promise.resolve('user data'); const p2 = Promise.reject('DB error'); const p3 = new Promise(resolve => setTimeout(() => resolve('cache data'), 100)); // Bails on p2, p3 result is discarded Promise.all([p1, p2, p3]).catch(err => console.log('all:', err)); // Output: all: DB error // Waits for all three, always resolves Promise.allSettled([p1, p2, p3]).then(results => console.log(results)); // Output: // [ // { status: 'fulfilled', value: 'user data' }, // { status: 'rejected', reason: 'DB error' }, // { status: 'fulfilled', value: 'cache data' } // ] ``` When `p2` rejects, `Promise.all` stops caring about `p3`. `Promise.allSettled` collects all three and resolves normally. ### Key difference `Promise.all` returns plain values in an array, but only when every promise fulfills. The first rejection triggers the outer promise to reject with that same error. The remaining promises still run to completion, their results are just ignored. `Promise.allSettled` never rejects. It resolves with an array of objects, each with a `status` field set to `'fulfilled'` or `'rejected'`, plus either `value` or `reason`. ### When to use - All results are required before moving on (fetching data for every widget on a dashboard): `Promise.all` - Partial failures are acceptable (batch image uploads, sending analytics events): `Promise.allSettled` - You need to log or audit every outcome, including failures: `Promise.allSettled` - Operations depend on each other (need user data before fetching permissions): `Promise.all` - You want to always respond to the client, even when some requests fail: `Promise.allSettled` ### Comparison table | Feature | Promise.all | Promise.allSettled | |---|---|---| | Resolves when | All promises fulfill | All promises settle | | Rejects when | Any promise rejects | Never | | Return value | Array of values | Array of `{status, value/reason}` | | Order preserved | Yes | Yes | | Empty array input | Resolves `[]` | Resolves `[]` | | Non-promise values | Treated as resolved | Treated as resolved | | Typical use case | Critical batch operations | Health checks, bulk uploads | ### How it works internally Both methods iterate the input and track a counter of pending promises. `Promise.all` attaches a single rejection handler that fires on the first failure and ignores everything else. `Promise.allSettled` attaches both `.then()` and `.catch()` to each promise individually, pushing a status object to the results array on every settle. When the counter hits zero, the outer promise resolves with the full array. Both follow the same spec since ES2020 and are available from Node.js 12.9+. ### Common mistakes **Expecting Promise.all to give partial results** ```javascript // Wrong: .then() never fires if rejectingP rejects Promise.all([p1, rejectingP, p3]) .then(results => console.log(results)); // Fix: switch to allSettled and filter Promise.allSettled([p1, rejectingP, p3]) .then(results => results .filter(r => r.status === 'fulfilled') .map(r => r.value) ); ``` **Forgetting that allSettled wraps results in objects** ```javascript // Wrong: result is an object, not the actual value for (const result of await Promise.allSettled(promises)) { processData(result); // passes {status, value} instead of the data } // Fix: check status before accessing the value for (const result of await Promise.allSettled(promises)) { if (result.status === 'fulfilled') processData(result.value); else logError(result.reason); } ``` **Using allSettled when operations depend on each other** ```javascript // Wrong: continues with undefined if fetchUser fails const results = await Promise.allSettled([fetchUser(id), fetchPermissions(id)]); const user = results[0].value; // undefined if rejected renderDashboard(user); // crashes // Fix: for dependent data, use Promise.all const [user, permissions] = await Promise.all([fetchUser(id), fetchPermissions(id)]); ``` **Passing non-promise values without knowing the behavior** ```javascript // Works, but mixing types hides intent Promise.all([1, 'hello', fetch('/api/data')]); // 1 and 'hello' become Promise.resolve(1) and Promise.resolve('hello') // Be explicit about what you're running concurrently ``` ### Real-world usage - React Query: `useQueries` uses `allSettled` internally so each query has its own loading and error state - Next.js: `getStaticPaths` fallback logic during build-time uses `allSettled` - Express batch endpoints: `allSettled` to always send a response, even when some DB queries fail - Puppeteer: `allSettled` for page scraping when some selectors may not exist on every page - Node.js CLI tools: `allSettled` for bulk file reads where some files might be missing ### Follow-up questions **Q:** What happens when you pass an empty array to either method? **A:** Both resolve immediately with `[]`. No rejection, no waiting. **Q:** What if the array contains a plain value like a number instead of a promise? **A:** Both coerce it to `Promise.resolve(value)`. With `allSettled`, it shows as `{status: 'fulfilled', value: number}`. **Q:** Does the output order match the input order? **A:** Yes, always. The order reflects the input array, not which promise settled first. **Q:** How does `Promise.any()` differ from these two? **A:** `Promise.any()` resolves as soon as the first promise fulfills and rejects only if every promise rejects. `Promise.allSettled` always waits for everything and never rejects. **Q (senior):** How would you polyfill `Promise.allSettled` for environments without native support? **A:** Wrap each promise with `.then(value => ({status: 'fulfilled', value})).catch(reason => ({status: 'rejected', reason}))`, then pass the array to `Promise.all`. Each wrapper always fulfills, so `Promise.all` never rejects and you get back the same shape as `allSettled`. ## Examples ### Fetching data for multiple API endpoints ```javascript const userIds = [1, 2, 3]; try { const users = await Promise.all( userIds.map(id => fetch(`/api/users/${id}`).then(r => r.json())) ); console.log(users); // [user1, user2, user3] } catch (err) { // One fetch failed, nothing rendered console.error('Fetch failed:', err); } ``` Use this when all data is required before rendering. If user 2 is missing, showing the others could mislead the user about what data is actually available. ### Express batch endpoint with partial success ```javascript app.get('/batch/users', async (req, res) => { const ids = req.query.ids.split(','); const results = await Promise.allSettled( ids.map(id => fetchUserFromDB(id)) ); const found = results .filter(r => r.status === 'fulfilled') .map(r => r.value); const failed = results .filter(r => r.status === 'rejected') .map((r, i) => ({ id: ids[i], error: r.reason.message })); res.json({ found, failed }); // Always responds, even when some DB queries fail }); ``` The client always gets a response and knows exactly which IDs worked and which did not. This pattern comes up often in admin tools and batch-action APIs. ### Bulk file reads with error tracking ```javascript const fs = require('fs').promises; const filePaths = ['./data/a.json', './data/b.json', './data/missing.json']; const results = await Promise.allSettled( filePaths.map(path => fs.readFile(path, 'utf-8').then(JSON.parse)) ); results.forEach((result, i) => { if (result.status === 'fulfilled') { console.log(`Loaded ${filePaths[i]}:`, result.value); } else { console.warn(`Skipped ${filePaths[i]}:`, result.reason.message); } }); // Processes a.json and b.json, logs a warning for missing.json ``` I've used this in data migration scripts where some source files are optional. With `Promise.all`, a single missing file would abort the entire run. `Promise.allSettled` processes everything it can and tells you what failed.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.