HuntExams Academy logo
JavaScriptAdvanced#async#promises

Difference between Promise.all, allSettled, race and any?

Answer

all resolves with every value but rejects on the first failure. allSettled always resolves with a status per promise. race settles with the first promise to settle either way. any resolves with the first fulfilment and rejects only if all fail.

Example

await Promise.all([a, b]);        // fails fast
await Promise.allSettled([a, b]); // [{status:'fulfilled'},{status:'rejected'}]
await Promise.race([a, timeout]); // whichever finishes first

Detailed explanation

Promise.all, Promise.allSettled, Promise.race, and Promise.any combine an iterable of promises or ordinary values into one promise. Their main difference is the condition that settles the returned promise: all successes, all outcomes, the first outcome, or the first success. Here, “settled” means either fulfilled or rejected. These methods register reactions on their inputs; they do not start tasks themselves or create threads. Operations such as fetch usually begin when called, before their promises reach the combinator.

Promise.all fulfils only when every input fulfils, returning an array of values in input order, not completion order. It rejects as soon as an input rejection is processed, using that rejection reason. Use it when all results are required, such as loading data needed to build one screen. Promise.allSettled waits for every input to settle and returns an input-ordered array of outcome objects. Each object contains either { status: 'fulfilled', value } or { status: 'rejected', reason }. For valid inputs, individual rejections do not reject this aggregate, making it useful for batch operations where partial success matters.

Promise.race adopts the first observed settlement, whether fulfilment or rejection. It is useful for a timeout wrapper, provided the timeout promise rejects when its timer expires. Promise.any instead ignores rejections while a fulfilment remains possible and returns the first fulfilled value. If every input rejects, it rejects with an AggregateError whose errors array contains rejection reasons in input order. This suits requests to alternative sources when any successful response is acceptable.

Interviewers often check cancellation and edge cases. None of these methods cancels unfinished operations; a timeout race can reject while the underlying request continues, so use AbortController where supported. With an empty iterable, all and allSettled fulfil with [], any rejects with AggregateError, and race remains pending forever. Ordinary values are treated as fulfilled inputs, and attached handlers still run asynchronously. Also distinguish input rejection from setup errors: even allSettled can reject if iterating its input throws.

Key points to remember

  • all: requires every input to fulfil; returns input-ordered values and rejects on the first observed rejection.
  • allSettled: waits for every outcome; returns input-ordered objects containing status and value or reason.
  • race: adopts the first observed settlement, whether fulfilled or rejected.
  • any: returns the first fulfilment; rejects with AggregateError only when every input rejects.
  • None cancels remaining work; empty inputs produce [] for all/allSettled, rejection for any, and permanent pending for race.

Common mistakes candidates make

  • Confusing race with any: race can reject even when another input later fulfils.
  • Assuming fail-fast rejection or a timeout race stops the remaining operations.
  • Expecting all or allSettled results in completion order, or expecting allSettled to return plain values.

Likely follow-up questions

Does Promise.all run tasks in parallel?

It observes the supplied inputs rather than starting their work. Asynchronous operations may overlap, but synchronous CPU-heavy JavaScript does not become parallel merely because it is wrapped in promises.

How do you implement a request timeout with Promise.race?

Race the request promise against a promise that rejects after a timer expires. Clear the timer when it is no longer needed, and use AbortController to stop a supported request if the timeout wins.

What happens if several inputs are already settled?

For already-settled native promises and ordinary values, reactions are queued in iteration order. Therefore, race takes the first input's outcome, while any takes the first fulfilled input; attached callbacks still execute asynchronously.

Interview tip: Explain each method by its settlement rule, then contrast race with any and mention that unfinished operations are not automatically cancelled.

Related Interview Questions

1
JavaScriptIntermediate#async

How does async/await work?

Open
2
JavaScriptIntermediate#async#performance

How do you run async calls in parallel with async/await?

Open
3
JavaScriptBeginner#async

What is callback hell and how do you avoid it?

Open