Promise.all() in JavaScript
Promise.all() is a static method of the Promise class that takes an array (or any iterable) of promises and returns a new promise. That promise fulfills when every promise in the list has fulfilled, and rejects as soon as the first one of them fails.
Theory
TL;DR
Promise.all(iterable)returns a new promise that aggregates a list of promises.fulfilled: when all input promises arefulfilled. The value is an array of results in the same order the promises were passed in, not in completion order.rejected: immediately after the first rejection, with that rejection's reason (fail-fast behaviour).- The remaining promises are not cancelled, they run to completion, but nobody will ever see their results.
- Plain values (non promises) are automatically wrapped with
Promise.resolve(). - Need every result even with failures? Then use
Promise.allSettled(), which never rejects.
Quick example
const p1 = Promise.resolve('A');
const p2 = Promise.resolve('B');
const p3 = Promise.resolve('C');
// The promise from Promise.all waits for all three at once.
Promise.all([p1, p2, p3]).then(values => console.log(values));
// ["A", "B", "C"]The syntax is as simple as it gets:
Promise.all(iterable)where iterable is usually an array of promises.
How it works
- All promises inside
Promise.all([...])run in parallel: more precisely, each of them already started independently of the others, because a promise begins its work the moment it is created. Promise.all()only waits for them to settle, it starts nothing itself.- If all of them succeed, a new promise in the
fulfilledstate is returned, and its value is an array of results in the same order as the input promises.
An example with delays:
const p1 = new Promise(res => setTimeout(() => res('First'), 1000));
const p2 = new Promise(res => setTimeout(() => res('Second'), 2000));
const p3 = new Promise(res => setTimeout(() => res('Third'), 500));
Promise.all([p1, p2, p3])
.then(results => console.log('Results:', results))
.catch(err => console.error('Error:', err));The output appears after roughly 2 seconds, that is, after the slowest promise rather than the sum of all delays:
Results: [ 'First', 'Second', 'Third' ]Result order and non promises
Results are ordered by position in the input array, even if one promise takes noticeably longer than the others:
Promise.all([
Promise.resolve('A'),
new Promise(res => setTimeout(() => res('B'), 2000)),
Promise.resolve('C')
]).then(console.log); // ["A", "B", "C"]If the array contains non promises, Promise.all() automatically wraps plain values into Promise.resolve():
Promise.all([42, Promise.resolve('OK')])
.then(console.log); // [42, "OK"]What happens if one of the promises rejects
If at least one promise inside Promise.all moves into the rejected state, the whole Promise.all() rejects immediately, and the result is the first error caught.
const p1 = Promise.resolve('OK');
const p2 = Promise.reject('Error!');
const p3 = Promise.resolve('Still OK');
Promise.all([p1, p2, p3])
.then(results => console.log('Success:', results))
.catch(err => console.error('Rejected:', err));Output:
Rejected: Error!The other promises (p1, p3) still run, but their results are ignored, because Promise.all() has already moved into the rejected state, and a promise changes state only once.
Handling errors without interrupting execution
If you need every promise to finish independently and errors not to interrupt the combined result, use Promise.allSettled():
Promise.allSettled([
Promise.resolve('OK'),
Promise.reject('Error'),
Promise.resolve('Still OK')
]).then(console.log);Output:
[
{ status: "fulfilled", value: "OK" },
{ status: "rejected", reason: "Error" },
{ status: "fulfilled", value: "Still OK" }
]Promise.allSettled() never rejects and returns an array of objects with status plus value or reason.
An alternative if you want to stay on Promise.all(): catch the error inside each promise separately, so no rejection ever reaches the aggregator.
const safe = p => p.catch(err => ({ error: err }));
Promise.all([p1, p2, p3].map(safe)).then(console.log);Comparison: all, allSettled, race
| Method | What it does | Success | Failure |
|---|---|---|---|
Promise.all() | Waits until all promises complete | Returns an array of results | Rejects on the very first error |
Promise.allSettled() | Waits for all of them, failures included | Returns an array of {status, value/reason} objects | Never rejects |
Promise.race() | Returns the result of the first settled promise | Can be either a success or an error | Rejects if the first settled promise was a rejected one |
A simple analogy:
Imagine you are waiting for three deliveries:
Promise.all(): you wait for all parcels together. If even one of them gets lost, you cancel the whole order.Promise.allSettled(): you also wait for all of them, and even if one arrives broken, you still get a report on every single one.
Common mistakes
- Thinking
Promise.all()starts the promises. It only waits: the promises started when they were created, so the wrapper does not parallelise anything extra. - Forgetting
.catch()ortry/catch. A rejection insidePromise.all()with no handler produces anunhandled promise rejection, which in Node.js can bring the process down. - Expecting the other promises to be cancelled. Promises are not cancellable: after the first rejection the rest keep running, consume resources and may even throw their own unhandled error.
- Expecting results in completion order. The array order always matches the input order, so do not sort results "by speed".
- Using
Promise.all()where partial results are needed. If one of ten requests is allowed to fail, reach forPromise.allSettled(). - Passing an already rejected promise into the array too late. For example, creating
Promise.reject()up front and handing it toPromise.all()later risks an unhandled rejection before the call even happens.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.