Promise.race()
Settled, not succeeded. A fast rejection beats a slow success, which makes race the natural way to impose a timeout and the wrong way to ask for the first working result.
Demo
Each input is [outcome, value, delay in ms]: 'ok' fulfils with the value, anything else rejects with an Error carrying it. Whatever settles first decides the outcome, win or lose. The second case is the one that matters: a rejection at 10ms beats a success at 50ms, so race is the right tool for a timeout and the wrong one for "try several sources and take whichever works" — that is Promise.any. One case is deliberately missing from this demo: an EMPTY list never settles at all, and a demo that waits forever is not a demo.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| iterable | iterable | yes | Any iterable. A non-promise value counts as already settled, so including one makes race resolve immediately with it. |
Return value
Promise — A Promise that settles exactly as the first input to settle does — fulfilled if that one fulfilled, rejected if it rejected.
Common patterns
const timeout = ms => new Promise((_, rej) => setTimeout(() => rej(new Error("timeout")), ms)); await Promise.race([fetchData(), timeout(5000)]);
await Promise.any([mirrorA(), mirrorB()]);
const c = new AbortController(); try { await Promise.race([fetch(u, {signal: c.signal}), timeout(5000)]); } finally { c.abort(); }
Examples
Pitfalls
await Promise.race([])
if (!tasks.length) return []; await Promise.race(tasks);
await Promise.race([failsFast, succeedsSlowly])
await Promise.any([failsFast, succeedsSlowly])
await Promise.race([fetch(url), timeout(1000)])
const c = new AbortController(); try { await Promise.race([fetch(url, {signal: c.signal}), timeout(1000)]); } finally { c.abort(); }
await Promise.race([fetchData, timeout(5000)])
await Promise.race([fetchData(), timeout(5000)])
When to use
- Timeouts, paired with an AbortController
- Taking the first response from several equivalent sources, when a failure should also abort
- Waiting for whichever of two events happens first
- You want the first SUCCESS → Promise.any
- You want every result → Promise.all or allSettled
- The iterable may be empty → guard it, or it hangs
- You need the losing work to stop → AbortController
Notes
FAQ
race settles on the first to FINISH either way; any resolves on the first to SUCCEED and only rejects if all of them fail. Use race for timeouts, any for redundancy.
Promise.race([work, timeout]); // whichever first Promise.any([mirrorA, mirrorB]); // whichever works