Promise.race()

Settles with the first promise to settle, whether that outcome is a fulfillment or a rejection.

Signature
Promise.race(iterable)
  • Added in JavaScript ES2015

Parameters

ParameterTypeDescription
$iterableIterableAn iterable, such as an Array, of promises. Values are awaited, so other thenables are resolved too; non-thenables are passed through as-is and count as already settled.

Return value

PromiseA Promise that asynchronously settles with the eventual state of the first input to settle — fulfilling if that one fulfilled, rejecting if it rejected. It stays pending forever if the iterable is empty.

Errors

TypeError if the argument is not iterable.

Promise.race() settles with whichever input settles first, and it does not care how it settled. A rejection that arrives first rejects the race, which is exactly the property that makes the timeout idiom work: race the real operation against a promise that rejects after N milliseconds and the loser is irrelevant.

The losers keep running

Nothing is cancelled. The slower operation continues to completion and still consumes its resources; its eventual outcome, fulfillment or rejection, is simply discarded. A losing rejection is not reported as unhandled, because race() attached its own handler to every input when it iterated them. If your work supports real cancellation, pair the race with an AbortController and abort the loser yourself.

Watch the already-settled inputs

Non-promise values and already-settled promises count as settled at the point race() iterates them, so the earliest such item in the array wins immediately — order in the iterable matters here in a way it does not for all(). Putting a plain value first makes the race a foregone conclusion.

Edge case

Promise.race([]) returns a promise that stays pending forever. Awaiting it hangs silently, with no error to tell you why.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Reject an operation that has not finished within a deadline
  • Take whichever of two redundant sources answers first
  • Stop waiting on a long poll when a shutdown signal fires
  • Surface the first error out of several concurrent operations

Frequently asked questions

How do I add a timeout to a promise?

Race it against a promise that rejects on a timer: Promise.race([work(), timeout(5000)]). Remember the work continues after the timeout fires unless you cancel it separately with something like an AbortController.

Does Promise.race cancel the slower promises?

No. Promises cannot be cancelled; the losers run to completion and their results are simply discarded.

What happens with Promise.race([])?

You get a promise that never settles. Awaiting it hangs indefinitely with no error, so guard against empty arrays before racing.

More examples

A rejection wins just as easily

The first race rejects after 5ms even though a success was on the way — race has no preference for fulfillment. The second shows a plain value winning outright, because it is already settled when race() reaches it.

Example · javascript
const delay = (ms, v) => new Promise((r) => setTimeout(() => r(v), ms));
const boom = (ms, m) => new Promise((_, rj) => setTimeout(() => rj(new Error(m)), ms));

console.log(
  await Promise.race([boom(5, "fast failure"), delay(50, "slow success")]).catch(
    (e) => "rejected: " + e.message,
  ),
);

console.log(await Promise.race(["already here", delay(0, "too late")]));

The loser carries on

quick wins the race at 15ms, but the ticker is untouched by losing — it keeps firing until its fifth tick and then resolves normally, showing that race() short-circuits only the combined result, never the work itself.

Example · javascript
let ticks = 0;
const ticker = new Promise((res) => {
  const id = setInterval(() => {
    if (++ticks === 5) { clearInterval(id); res("ticker done"); }
  }, 10);
});
const quick = new Promise((res) => setTimeout(() => res("quick done"), 15));

console.log("winner:", await Promise.race([ticker, quick]));
console.log("loser eventually:", await ticker, "ticks:", ticks);

Discussion

  • Be the first to comment on this lesson.