JavaScript Asynchronous Programming with Promise any()
Promise.any() is a powerful JavaScript method introduced in ECMAScript 2021 that allows you to handle multiple promises simultaneously. This method returns a single promise that resolves as soon as any one of the input promises fulfills, making it ideal for scenarios where you want the fastest successful result.
Browser and Node.js Compatibility
Node.js: 15.0.0+ (native support)
Chrome: 85+
Firefox: 79+
Safari: 14+
For optimal compatibility and performance, we recommend using the latest Node.js LTS version.
How Promise.any() Works
Promise.any() takes an iterable of promises and returns a promise that:
- Resolves with the value of the first successfully fulfilled promise
- Rejects only if all input promises are rejected
Key Characteristics:
- Returns the first successful promise (not necessarily the fastest)
- Ignores rejected promises until all promises fail
- Perfect for fallback strategies and redundancy
Practical Examples
Example 1: First Successful Promise Wins
// Create promises with different resolve/reject patterns
const fastPromise = new Promise((resolve, reject) => {
setTimeout(reject, 100, "fast: rejected");
});
const mediumPromise = new Promise((resolve, reject) => {
setTimeout(reject, 99, "medium: rejected");
});
const slowPromise = new Promise((resolve, reject) => {
setTimeout(resolve, 50, "slow: resolved");
});
const veryFastPromise = new Promise((resolve, reject) => {
setTimeout(() => resolve('very fast: resolved'), 205);
});
// Use Promise.any() to get the first successful result
Promise.any([slowPromise, mediumPromise, fastPromise, veryFastPromise])
.then((result) => {
console.log("First successful promise:", result);
// Output: "slow: resolved"
})
.catch(error => {
console.log("All promises failed");
});
Example 2: Handling Complete Failure
// All promises will be rejected
const rejectedFast = new Promise((resolve, reject) => {
setTimeout(reject, 100, "fast: rejected");
});
const rejectedMedium = new Promise((resolve, reject) => {
setTimeout(reject, 99, "medium: rejected");
});
const rejectedSlow = new Promise((resolve, reject) => {
setTimeout(reject, 50, "slow: rejected");
});
const rejectedVeryFast = new Promise((resolve, reject) => {
setTimeout(() => reject('very fast: rejected'), 205);
});
Promise.any([rejectedSlow, rejectedMedium, rejectedFast, rejectedVeryFast])
.then((result) => {
console.log("Success:", result);
})
.catch(error => {
console.log("Total failures:", error.errors.length);
// Iterate through all rejection reasons
error.errors.forEach((rejection, index) => {
console.log(`Failure ${index + 1}:`, rejection);
});
});
// Output:
// Total failures: 4
// Failure 1: slow: rejected
// Failure 2: medium: rejected
// Failure 3: fast: rejected
// Failure 4: very fast: rejected
Error Handling Best Practices
Always include a .catch() block when using Promise.any(). Without proper error handling, you might encounter:
UnhandledPromiseRejection: This error originated either by throwing inside of
an async function without a catch block, or by rejecting a promise which was
not handled with .catch(). The promise rejected with the reason "slow promise
Rejected".
Proper Error Handling Pattern:
Promise.any([promise1, promise2, promise3])
.then(result => {
// Handle successful result
console.log("Success:", result);
})
.catch(error => {
// Handle case where all promises failed
console.log("All promises rejected");
console.log("Rejection reasons:", error.errors);
})
.finally(() => {
// Cleanup code that runs regardless of outcome
console.log("Operation completed");
});
Real-World Use Cases
1. Multiple API Endpoints with Fallback
const primaryAPI = fetch('https://primary-api.com/data');
const backupAPI = fetch('https://backup-api.com/data');
const cacheAPI = fetch('https://cache-api.com/data');
Promise.any([primaryAPI, backupAPI, cacheAPI])
.then(response => response.json())
.then(data => {
console.log("Data from fastest available source:", data);
})
.catch(() => {
console.log("All data sources unavailable");
});
2. Resource Loading with Redundancy
const cdn1 = loadScript('https://cdn1.com/library.js');
const cdn2 = loadScript('https://cdn2.com/library.js');
const cdn3 = loadScript('https://cdn3.com/library.js');
Promise.any([cdn1, cdn2, cdn3])
.then(() => {
console.log("Library loaded successfully");
initializeApp();
})
.catch(() => {
console.error("All CDNs failed - using local fallback");
loadLocalFallback();
});