Promise combinators: all, allSettled, race and any
Pick the right way to wait for many promises. How Promise.all fails fast, what allSettled, race and any return, their empty-array cases, and how to write Promise.all.
Comes up in: JavaScript, Coding
Learn#
Neha’s home page loads profile, orders and offers together. When the offers service fails, the whole page shows an error, even though profile and orders arrived.
She used Promise.all. It is a combinator: a function that turns many promises into one. There are four, and each answers a different question:
const ok = (v, ms) => new Promise((r) => setTimeout(() => r(v), ms));
const no = (m, ms) => new Promise((_, r) => setTimeout(() => r(new Error(m)), ms));
const show = (p) => p.then((v) => JSON.stringify(v), (e) => `rejected: ${e.message}`);
console.log("all:", await show(Promise.all([ok("a", 60), ok("b", 10)])));
console.log("all:", await show(Promise.all([ok("a", 60), no("b down", 10)])));
const settled = await Promise.allSettled([ok("a", 10), no("b down", 20)]);
console.log("allSettled:", settled.map((r) => r.status).join(", "));
console.log("race:", await show(Promise.race([ok("slow", 60), no("fast error", 10)])));
console.log("any:", await show(Promise.any([no("x", 10), ok("second", 30)])));Output (verified)
all: ["a","b"] all: rejected: b down allSettled: fulfilled, rejected race: rejected: fast error any: "second"
Network
- profile …
- orders …
- offers …
State
empty
Console
empty
The page asks for three widgets at once: profile (60 ms), orders (10 ms), offers (20 ms).
Read the steps as text
- The page asks for three widgets at once: profile (60 ms), orders (10 ms), offers (20 ms).
- orders finishes first. Promise.all stores its value in slot 1, not at the end.
- offers fails. Promise.all rejects at once with that error; it does not wait for profile.
- allSettled instead waits for all three and reports each one's status.
Results keep input order, whatever order the promises finish in. Promise.all is fail-fast: the first rejection rejects it.
Predict#
Predict first
What does Promise.race([]) do?
With nothing to race, nothing can settle it, so it never settles. Promise.all([]) and allSettled([]) resolve to [], and Promise.any([]) rejects with an AggregateError. People guess “undefined” because the other three do something at once.
Interview angle#
Say it like this — about 30 seconds
“Promise.all resolves to every value in input order, and rejects as soon as one rejects. allSettled never rejects; it gives each result’s status and value or reason. race settles like the first promise to settle, success or failure. any resolves with the first success and rejects with an AggregateError only if all fail. For empty input: all and allSettled give an empty array, any rejects, and race stays pending.”
Follow-up Does Promise.all cancel the other promises when one fails?
Follow-up Which would you use for a dashboard of independent widgets?
allSettled, so one failing widget shows its own error while the others render.Follow-up How do you implement Promise.all?
Practice#
On your own
Write promiseAll and promiseAny without calling the built-in versions.
Done when
promiseAllkeeps input order and accepts plain values.promiseAllrejects with the first error, and resolves[]for empty input.promiseAnyresolves with the first success, and rejects with an AggregateError of all reasons in input order.
Remember#
Try to answer each card before you open it. Then add them to your reviews.
When does Promise.all reject?
As soon as any input promise rejects (fail-fast).
Can Promise.allSettled reject?
No. It resolves with a status object for every input.
What does Promise.any reject with?
An AggregateError holding every rejection reason.
What does Promise.race([]) do?
Stays pending forever.
In what order does Promise.all return values?
Input order, not the order they finish.
Go deeper
Four layers. Stop at the one your interview needs; each ends with a quick check.
The core ideaEvery round
all. Independent tasks: allSettled. A deadline or the fastest of several sources: race or any. any skips failures; race does not.Check yourself: Which combinator gives the first success and ignores early failures?
Promise.any
How it works underneathSenior rounds
Each combinator calls Promise.resolve on every item, so plain values work, then attaches handlers. Promise.all writes each value to its own index and counts how many remain Source: ECMA-262: Promise.all. The input can be any iterable, such as a Set.
Check yourself: Why does Promise.all call Promise.resolve on each item?
So plain values and thenables are handled like promises.
Edge cases and trapsWhere people slip
all and allSettled resolve to [], any rejects with an AggregateError with no errors, and race stays pending forever Source: MDN: Promise.any().race.Check yourself: What do Promise.all([]) and Promise.any([]) do?
all resolves to []; any rejects with an AggregateError.
In productionStaff-level answers
Promise.all starts nothing; it waits for promises you already started. Mapping 500 URLs to fetch starts 500 requests at once, so add a concurrency limit (JS.11.07). Time limits with race leave the slow work running; prefer an abort signal (JS.11.06).
Check yourself: What should you add when you start 500 requests with Promise.all?
A concurrency limit, so only a few run at once.
Finished the five steps? Mark it, and its cards join your reviews.
Last checked 2026-10-31. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.
Interview questions this answers
- Explain the difference between
Promise.all,allSettled,raceandany. What does each return for an empty array? - Implement
Promise.all.