Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose Promise.all() when every operation must fulfill, Promise.allSettled() when you need the final result of every operation regardless of success or failure, and Promise.race() when the first settlement—success or failure—should determine the result. None of them cancels the work that loses or continues after the aggregate settles.

Quick comparison

What you need Use Aggregate behavior Returned data
Every operation must succeed Promise.all() Rejects when an input rejects; otherwise fulfills after all inputs fulfill. An array of fulfillment values in input order.
The outcome of every operation, including failures Promise.allSettled() Fulfills after every input settles. An array of records containing each input’s status and its value or rejection reason, in input order.
The first success or failure to settle Promise.race() Settles with the state of the first input to settle. The winning value or rejection reason.

When to use Promise.all()

Use Promise.all(iterable) when the combined result is useful only if every operation succeeds—for example, when an interface requires several successful responses before it can render a complete view. If any input rejects, the aggregate rejects with the first rejection reason it observes; it does not return partial results. If all inputs fulfill, the aggregate fulfills with their values in the same order as the iterable, not the order in which they finished. See MDN’s Promise.all() reference.

Example

const [user, settings] = await Promise.all([
  fetchUser(),
  fetchSettings(),
]);

This is appropriate when both results are required. If either call rejects, the await throws and control follows the usual rejection path, such as a surrounding try/catch.

Start operations before passing them

A combinator accepts promises (and other values), not uncalled async functions that it should invoke. Call each function to obtain its promise, then pass those promises to the method. For example, pass fetchUser(), not fetchUser.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When to use Promise.allSettled()

Use Promise.allSettled(iterable) when tasks are independent and you need to handle each final outcome, rather than treating one failure as failure of the whole group. It fulfills only after every input has either fulfilled or rejected. Each result record has a status of "fulfilled" or "rejected"; fulfilled records contain value, while rejected records contain reason. The records stay in input order. See MDN’s Promise.allSettled() reference.

Example

const results = await Promise.allSettled([
  saveDraft(),
  refreshRecommendations(),
]);

for (const result of results) {
  if (result.status === "fulfilled") {
    console.log("Completed:", result.value);
  } else {
    console.error("Failed:", result.reason);
  }
}

This pattern suits batch work where one failure should be recorded without hiding the results of other tasks. It does not return early when a rejection occurs; it waits for every input to settle.

When to use Promise.race()

Use Promise.race(iterable) when whichever input settles first should decide the aggregate’s result. “Settles” includes both fulfillment and rejection: the first rejection can win just as the first fulfillment can. The aggregate adopts that input’s state and result, without waiting for the remaining inputs to settle. See MDN’s Promise.race() reference.

Example: impose a response deadline

const result = await Promise.race([
  fetchData(),
  new Promise((_, reject) => {
    setTimeout(() => reject(new Error("Timed out")), 3000);
  }),
]);

In this example, the aggregate rejects if the timer rejects first; that rejection does not stop fetchData(). A race is not the right method when the requirement is specifically “return the first successful result.” That is a distinct use case for Promise.any(), which fulfills when an input fulfills.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

An empty iterable is a special case: Promise.race([]) remains pending forever. See MDN’s Promise.race() reference.

Do these methods cancel the other operations?

No. Promise.all() may reject as soon as a rejection determines its result, and Promise.race() may settle as soon as one input settles, but neither method cancels the other work. The remaining operations continue unless their underlying APIs support cancellation and your code requests it. MDN’s Using promises guide explains that Promise.all() immediately rejects its returned promise when an input rejects; early settlement of that aggregate is not cancellation of the other inputs.

For cancellable operations, such as supported web requests, pass and use an AbortSignal with the underlying operation. The combinator coordinates outcomes; cancellation must be handled separately.

Do they run JavaScript in parallel?

No. These methods coordinate the outcomes of promises; choosing one does not itself create parallel JavaScript execution. As MDN explains in its Promise overview, JavaScript executes one task at a time in a given thread. Work can overlap when asynchronous operations are in progress, but actual parallel execution requires mechanisms such as worker threads.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Empty inputs and non-promise values

  • Promise.all([]) fulfills with an empty array.
  • Promise.allSettled([]) fulfills with an empty array.
  • Promise.race([]) stays pending forever.
  • All three methods accept an iterable, commonly an array. Values that are not promises are accepted too; they are treated as already fulfilled inputs.

For non-empty inputs, Promise.all() and Promise.allSettled() preserve iterable order in their returned arrays, even when operations finish in a different order. See the Promise.all() and Promise.allSettled() references.

A practical decision rule

  1. Ask whether every operation must fulfill for the result to be useful. If yes, choose Promise.all().
  2. If failures should be reported alongside successes and you need every final outcome, choose Promise.allSettled().
  3. If one result should decide as soon as it settles, whether that result fulfills or rejects, choose Promise.race().
  4. If work that is no longer needed must stop, arrange cancellation in the underlying operations; none of these combinators does that for you.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.