Promise.all vs race vs allSettled vs any in JS
JavaScript provides four static concurrency methods—known as Promise
combinators—to manage multiple asynchronous operations running in
parallel: Promise.all, Promise.race,
Promise.allSettled, and Promise.any. While all
four accept an iterable of Promises, they differ significantly in their
completion criteria, short-circuiting behaviors, and how they handle
fulfillments versus rejections.
Promise.all
Promise.all accepts an iterable of promises and fulfills
only when all input promises have fulfilled. It returns
a single promise that resolves to an array of the fulfilled values in
the exact order of the original input.
- Fulfillment: Resolves when all promises resolve successfully.
- Rejection (Fail-Fast): Rejects immediately as soon as any single promise rejects, discarding the results of any remaining pending promises.
- Best Use Case: Interdependent tasks where every single operation is required to proceed (e.g., fetching a user profile, account settings, and permissions simultaneously).
Promise.allSettled
Promise.allSettled waits until every
input promise has settled, meaning each has either fulfilled or
rejected. It never short-circuits on a rejection.
- Fulfillment: Always fulfills after all promises have finished executing, regardless of whether they succeeded or failed.
- Rejection: It never rejects.
- Return Value: Resolves to an array of objects. Each
object contains a
status("fulfilled"or"rejected") along with avalue(if fulfilled) or areason(if rejected). - Best Use Case: Independent tasks where you need the complete outcome of every operation, even if some fail (e.g., sending batch notification emails or rendering a dashboard with independent widgets).
Promise.race
Promise.race settles as soon as the
first promise in the iterable settles, whether that
first outcome is a fulfillment or a rejection.
- Fulfillment: Resolves if the fastest promise fulfills.
- Rejection: Rejects if the fastest promise rejects.
- Best Use Case: Setting up request timeouts (e.g., racing a network fetch against a promise that rejects after 5 seconds) or querying multiple equivalent data sources where you want the quickest response.
Promise.any
Promise.any waits for the first
fulfilled promise. Unlike Promise.race, it ignores
rejections as long as there is at least one promise that might still
fulfill.
- Fulfillment: Resolves with the value of the first promise that fulfills successfully.
- Rejection: Rejects only if all
input promises reject, returning an
AggregateErrorcontaining all individual rejection reasons. - Best Use Case: Redundant requests where you need data from any working source (e.g., querying mirror servers or fallback APIs where one successful response is sufficient).
Summary Comparison
| Method | Fulfills When | Rejects When | Short-Circuits On |
|---|---|---|---|
Promise.all |
All promises fulfill | Any promise rejects | First rejection |
Promise.allSettled |
All promises settle | Never rejects | None (waits for all) |
Promise.race |
First promise fulfills | First promise rejects | First settlement (fulfillment or rejection) |
Promise.any |
First promise fulfills | All promises reject | First fulfillment |