JavaScript Promise.race vs Promise.any: What You Need to Know

Abhishek PorwalAbhishek Porwal
3 min read

Working with asynchronous operations in JavaScript often means juggling multiple Promises. In many real-world situations, we donโ€™t just wait for all Promises (Promise.all) โ€” sometimes we care about which Promise finishes first, or we want the first successful response among several.

Thatโ€™s where Promise.race and Promise.any come into play.

In this post, weโ€™ll go over what they do, how they differ, and when to use each โ€” with concise examples and practical scenarios.

๐Ÿ Promise.race: First Settled Promise Wins

Promise.race() returns a Promise that resolves or rejects as soon as any one of the input Promises settles. It doesnโ€™t matter whether that Promise fulfilled or reject.

Example:

const fast = new Promise(resolve => setTimeout(() => resolve("Fast"), 100));
const slow = new Promise(resolve => setTimeout(() => resolve("Slow"), 500));

Promise.race([fast, slow])
  .then(result => console.log(result)); // Output: "Fast"

Even if some Promises are still pending, Promise.race completes as soon as one finishes โ€” regardless of success or failure.

What if the first Promise rejects?

const failFast = new Promise((_, reject) => setTimeout(() => reject("Error"), 100));
const succeedSlow = new Promise(resolve => setTimeout(() => resolve("Success"), 500));

Promise.race([failFast, succeedSlow])
  .catch(error => console.error(error)); // Output: "Error"

โœ… Promise.any: First Fulfilled Promise Wins

Promise.any() returns a Promise that resolves as soon as any of the input Promises fulfilled. It ignores rejections unless all Promises fail โ€” in which case it rejects with an AggregateError.

Example:

const fail1 = Promise.reject("Failed A");
const fail2 = Promise.reject("Failed B");
const succeed = new Promise(resolve => setTimeout(() => resolve("Success"), 300));

Promise.any([fail1, fail2, succeed])
  .then(result => console.log(result)); // Output: "Success"

If all Promises reject:

Promise.any([
  Promise.reject("Error 1"),
  Promise.reject("Error 2")
])
.catch(error => {
  console.error(error.name); // "AggregateError"
  console.error(error.errors); // ["Error 1", "Error 2"]
});

๐Ÿ” Key Differences: race vs any

FeaturePromise.racePromise.any
Settles whenFirst promise fulfills or rejectsFirst promise fulfills
Ignores rejections?โŒ Noโœ… Yes
Fails if all reject?โŒ No, depends on first to settleโœ… Yes, throws AggregateError
Common use casesTimeouts, cancel-on-error patternsRedundant APIs, first-success logic

๐Ÿ› ๏ธ Real Use Cases

โœ… Using Promise.race for timeouts

One common scenario is setting a timeout for an API request:

const fetchWithTimeout = (url, timeout = 3000) => {
  return Promise.race([
    fetch(url),
    new Promise((_, reject) => setTimeout(() => reject("Timeout"), timeout))
  ]);
};

โœ… Using Promise.any to fetch from multiple endpoints

If you have multiple endpoints or mirrors and want the first successful response:

const urls = [
  "https://primary.example.com/data",
  "https://backup1.example.com/data",
  "https://backup2.example.com/data"
];

Promise.any(urls.map(url => fetch(url)))
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error("All requests failed:", error));

๐Ÿงฉ Summary

  • Use Promise.race when you care about the first Promise to settle, regardless of outcome.

  • Use Promise.any when you want the first successful result, and can ignore failures.

Both are powerful tools when used in the right context, especially for improving performance and resilience in distributed or network-heavy applications.

0
Subscribe to my newsletter

Read articles from Abhishek Porwal directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Abhishek Porwal
Abhishek Porwal

Passionate Frontend Developer with over 2.5 years of experience specializing in creating dynamic, responsive, and user-friendly web applications using React.js. While my primary focus is on front-end development, I have a foundational understanding of the full MERN stack, including MongoDB, Express.js, and Node.js. Committed to continuous learning and staying updated with the latest technologies, I thrive on bringing innovative ideas to life and delivering high-quality, scalable solutions. Let's connect and share knowledge on Hashnode!