Promise.all, race, allSettled, and any all behave differently when rejections appear — and interviewers test exactly those edges. Ten questions covering when each combinator resolves, what shape its value has, and the key difference between race and any on the first rejection.
Q1 — Promise.all with all resolved — order is input order
Loading editor...
Show answer
Output:
["first", "second", "third"]
Why: Promise.all waits for every Promise in the array and returns their values in input order, not resolution order. Even if the second Promise resolved before the first, the array position is preserved. Here all three are already resolved, so the array is ["first", "second", "third"].
Q2 — Promise.all with one rejection
Loading editor...
Show answer
Output:
caught: error
Why: Promise.all is fail-fast — as soon as any Promise rejects, the whole thing rejects with that reason. The values from 1 and 3 are discarded. The .catch() (or try/catch with await) fires with "error". The other Promises are not cancelled — they continue running — but their results are ignored.
Q3 — Promise.all with an empty array
Loading editor...
Show answer
Output:
[]
0
Why: Promise.all([]) resolves immediately with an empty array — there are no Promises to wait for. This is a useful edge case when you're building the array dynamically and it might be empty. No microtask tick is needed; the resolution is synchronous within the Promise machinery.
Q4 — Promise.race — first settled wins
Loading editor...
Show answer
Output:
fast
Why: Promise.race resolves (or rejects) with the first Promise that settles — regardless of whether it resolved or rejected. fast resolves after 100ms, slow after 200ms. fast wins. Once race has settled, the result of slow is permanently ignored.
Q5 — Promise.race where the first settles as a rejection
Loading editor...
Show answer
Output:
catch: fail
Why: Promise.race doesn't prefer resolved Promises — it picks whichever settles first, including rejections. rejected settles at 100ms with a rejection, so the race result is a rejection. resolved settles later at 200ms but its result is ignored. Many developers assume race only picks resolved Promises — it doesn't.
Q6 — Promise.allSettled never rejects
Loading editor...
Show answer
Output:
3
rejected
fail
Why: Promise.allSettled never rejects. It waits for all Promises to settle and returns an array of descriptor objects — one per Promise, in input order. Fulfilled Promises give {status: "fulfilled", value: ...}. Rejected Promises give {status: "rejected", reason: ...}. This is the right tool when you want all results regardless of failures.
Q7 — Promise.allSettled output shape in full
Loading editor...
Show answer
Output:
{"status":"fulfilled","value":42}
{"status":"rejected","reason":"oops"}
Why: The shape is fixed: fulfilled descriptors have status and value; rejected descriptors have status and reason. There is no value key on rejected descriptors and no reason key on fulfilled ones. This is important when you consume allSettled results — always check status before accessing value or reason.
Q8 — Promise.any — first fulfilled wins, skips rejections
Loading editor...
Show answer
Output:
any: first resolve
Why: Promise.any returns the first fulfilled Promise, ignoring rejections. The first element is a rejection — any skips it and waits for the next fulfillment. "first resolve" is the first to fulfill, so that's the result. Unlike Promise.race, a rejection does not settle any.
Q9 — Promise.any when all reject — AggregateError
Loading editor...
Show answer
Output:
true
["e1", "e2", "e3"]
Why: When all Promises passed to Promise.any reject, it rejects with an AggregateError — a special Error subtype that holds all the rejection reasons in its .errors array, in input order. This is the only way Promise.any ever rejects. e.message is "All promises were rejected".
Q10 — Promise.any vs Promise.race when the first settles as rejection
Loading editor...
Show answer
Output:
race catch: rejected first
any: resolved second
Why: This is the critical difference between the two:
Promise.racestops on the first settlement — resolved or rejected.firstis already rejected synchronously (the executor runs sync), soraceimmediately rejects with"rejected first".Promise.anystops on the first fulfillment. It skips the rejection and waits forsecondto resolve after 100ms, then fulfills with"resolved second".
Use race when you want the fastest result regardless. Use any when you want the fastest success.
Key Rules
| Combinator | Resolves when | Rejects when | Value shape |
|---|---|---|---|
Promise.all | All resolve | Any one rejects (fail-fast) | Array in input order |
Promise.race | First settles (resolve OR reject) | First settles as rejection | That one value/reason |
Promise.allSettled | All settle (never rejects) | Never | Array of {status,value} or {status,reason} |
Promise.any | First resolves | All reject | That one value / AggregateError |
Key distinction — race vs any:
race: first to settle wins, including rejectionsany: first to fulfil wins; rejections are skipped until all reject
Go Deeper
- Output Quiz #7 — Promise Chaining & the .catch() Recovery Rules — the previous quiz
- Output Quiz #9 — async/await Patterns & the return vs return await Trap — the next quiz
- Output Quiz #6 — Promises & async/await Ordering — basics: executor timing, .then() as microtask
