Howto Use Promise.any(): When First Success Is Enough
Why Promise.any() is the async method you didn’t know you needed
JavaScript’s Promise API offers several patterns for managing asynchronous tasks. You’ve probably used Promise.all() or Promise.race() before, but sometimes you only care about the first successful result, even if others fail. That’s where Promise.any() shines.
It resolves as soon as one promise fulfills, ignoring failures (unless all fail). This makes it a powerful tool for resilient and user-friendly async workflows.
How Promise.any() Works
Promise.any(iterable)
Takes an iterable of promises.
Resolves with the first fulfilled promise.
Rejects with an AggregateError if all promises reject.
With an empty iterable, it immediately rejects with an empty
AggregateError.
Real-World Use Cases
1. Fallback APIs
Suppose you have multiple mirror servers and only need the first working one:
const fetchWithCheck = (url) =>
fetch(url).then((res) => {
if (!res.ok) throw new Error(`HTTP error: ${res.status}`);
return res;
});
Promise.any([
fetchWithCheck("https://mirror1.example.com/data"),
fetchWithCheck("https://mirror2.example.com/data"),
fetchWithCheck("https://mirror3.example.com/data"),
])
.then((res) => res.json())
.then((data) => console.log("First available data:", data))
.catch((err) => {
if (err instanceof AggregateError) {
console.error("All servers failed:", err.errors);
} else {
console.error("Unexpected error:", err);
}
});
2. Progressive Feature Fallback
Gracefully handle modern vs. legacy APIs:
const tryClipboard = () =>
navigator.clipboard.readText().then((txt) => `Clipboard: ${txt}`);
const tryPrompt = () =>
new Promise((resolve, reject) => {
const txt = prompt("Paste your data:");
txt === null
? reject(new Error("User canceled input"))
: resolve(`Prompt: ${txt}`);
});
Promise.any([tryClipboard(), tryPrompt()])
.then((result) => console.log("Got user input:", result))
.catch((err) => {
if (err instanceof AggregateError) {
console.error("No input methods available:", err.errors);
}
});
Even if clipboard access fails, the prompt fallback ensures the feature still works.
Common Pitfalls
Resolves on the first success, ignores later rejections.
Rejects with
AggregateErrorif all promises fail.Does not cancel other running promises (use
AbortControllerfor cancellation).Promises start immediately;
Promise.any()doesn’t delay execution.An empty iterable → rejects instantly with an empty
AggregateError.
Example: Handling AggregateError
Promise.any([
Promise.reject(new Error("Failure A")),
Promise.reject(new Error("Failure B")),
])
.catch((err) => {
console.log(err instanceof AggregateError); // true
console.log(err.errors.map((e) => e.message)); // ["Failure A", "Failure B"]
});
Сomparison with Other Methods
To understand where Promise.any() fits in, let’s compare it with other common Promise helpers:
Promise.all()— Resolves only when every promise succeeds. If even one fails, the whole thing rejects. Use it when you really need all results.Promise.race()— Resolves or rejects as soon as the first promise settles, regardless of success or failure. Perfect for timeout races or fallback logic.Promise.allSettled()— Waits for everything to finish, then returns the status of each promise (fulfilled or rejected). Use this when you need to handle results individually.Promise.any()— Resolves as soon as the first success happens, and ignores failures unless all of them fail. Great for fallbacks and “just give me something that works” scenarios.
Browser & Node.js Support
Chrome 85+, Firefox 79+, Safari 14+, Edge 85+
Node.js 15+
For older environments: polyfill with core-js.
When Not to Use Promise.any()
Avoid Promise.any() if:
You need all results → use
Promise.all().You want the fastest outcome (success or failure) → use
Promise.race().You must handle every result individually → use
Promise.allSettled().
Success-First Async Practice
Promise.any() embraces the reality of unreliable networks and partial failures. It’s an elegant solution when one success is enough — whether that’s the first healthy API, the first working browser feature, or the first fallback to respond.
Recently, we wrote about Promise.try(), another helpful utility for unifying sync and async flows. Combined with Promise.any(), you gain a flexible async toolkit that handles both certainty and failure-tolerance gracefully.
So next time you design an async workflow, ask:
👉 Do I need every result, or is one success enough?
If the latter — reach for Promise.any().



Great write-up now real question, how often do we actually wait for all the answers when one will do?