JavaScript Asynchronous Programming with Promise any()

 ← Dev Articles
👍 0
👎 0

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();

 });