Suggest an editImprove this articleRefine the answer for “Promise.any() in JavaScript”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`Promise.any(iterable)` takes an array (or any iterable) of promises and returns a new promise that fulfills with the value of the first promise to succeed, ignoring every rejection along the way. If all promises reject, it rejects with a special `AggregateError` whose `errors` field holds an array of all the reasons in input order.** ```javascript Promise.any([Promise.reject('Error 1'), Promise.resolve('Success')]) .then(console.log) // Success .catch(err => console.error(err.errors)); ``` **Key point:** `any()` means "give me the first successful result", unlike `race()`, which reacts to the first settled promise even when that one is rejected.Shown above the full answer for quick recall.Answer (EN)Image**`Promise.any(iterable)` takes an array (or any iterable) of promises and returns a new promise that fulfills as soon as the first promise succeeds (`resolve`).** It rejects only when every promise has rejected, so the logic reads as: "give me the first successful result and ignore the errors". ## Theory ### TL;DR - `Promise.any(iterable)` yields the value of the **first successful** promise. - Intermediate rejections are ignored, they do not stop the waiting. - If **all** of them reject, the returned promise fails with an `AggregateError`. - `err.errors` holds an array of every rejection reason. - Non promises are wrapped into `Promise.resolve()`, so a plain value wins right away. - The classic scenario: a fallback across several data sources, or redundant API requests. ### Quick example ```javascript const p1 = Promise.reject('Error 1'); const p2 = new Promise(resolve => setTimeout(() => resolve('Success 2'), 1000)); const p3 = new Promise(resolve => setTimeout(() => resolve('Success 3'), 2000)); Promise.any([p1, p2, p3]) .then(result => console.log('Result:', result)) .catch(err => console.error('Error:', err)); ``` The output after 1 second: ```javascript Result: Success 2 ``` The first successful one (`p2`) wins, even if the others are still running or will fail later. Syntax: ```javascript Promise.any(iterable) ``` It returns a new `Promise` that settles with the value of the **first `fulfilled` promise**, or rejects with the special `AggregateError` if every promise failed. ### How it works under the hood 1. All promises run **in parallel**, or more precisely each one has been running since it was created. 2. If at least one of them **succeeds** (`resolve`), `Promise.any()` **settles immediately with that result**. 3. If **all** of them turn out `rejected`, an **error of type `AggregateError`** is returned with an array of all the reasons. So a rejection does not end the waiting: the failure counter simply grows, and only when it matches the number of promises does `catch` fire. ### If all promises reject ```javascript const p1 = Promise.reject('Error A'); const p2 = Promise.reject('Error B'); Promise.any([p1, p2]) .then(console.log) .catch(err => console.error(err)); ``` Output: ```javascript AggregateError: All promises were rejected ``` The error carries the **list of all reasons**: ```javascript err.errors // ['Error A', 'Error B'] ``` A closer look at how `AggregateError` behaves: ```javascript Promise.any([ Promise.reject('Error 1'), Promise.reject('Error 2') ]).catch(err => { console.error(err.name); // AggregateError console.error(err.errors); // ['Error 1', 'Error 2'] }); ``` The order inside `err.errors` matches the order of the input promises, not the order in which they rejected. ### A mix of successes and failures ```javascript const slow = new Promise(resolve => setTimeout(() => resolve('Slow success'), 2000)); const fail = Promise.reject('Error!'); const fast = new Promise(resolve => setTimeout(() => resolve('Fast success'), 500)); Promise.any([slow, fail, fast]) .then(console.log) .catch(console.error); ``` The result after 0.5 seconds: ```javascript Fast success ``` Even though `fail` failed before anyone else, `Promise.any()` waits for the first **successful** promise. ### Falling back across several sources Imagine you have three servers and need data **from the first one that answers successfully**, even if the other two are unavailable: ```javascript const fetchFromA = fetch('/api/a'); // may fail const fetchFromB = fetch('/api/b'); const fetchFromC = fetch('/api/c'); Promise.any([fetchFromA, fetchFromB, fetchFromC]) .then(res => console.log('Response received')) .catch(() => console.error('All sources are unavailable')); ``` That is how a fallback strategy is built: **success from any source counts as enough**. ### How it differs from the other methods | Method | What it returns | Settles when | Fails when | | --- | --- | --- | --- | | `Promise.all()` | An array with every successful result | All promises are `fulfilled` | The first `reject` | | `Promise.allSettled()` | An array of statuses (`fulfilled` / `rejected`) | All promises are settled | Never | | `Promise.race()` | The first settled promise (success or failure) | Any `resolve` or `reject` | It settles on the first `reject` | | `Promise.any()` | The first successful result | The first `fulfilled` | When **all** are `rejected` | In other words: - `Promise.race()` reacts to the **first settled** promise, failures included; - `Promise.any()` reacts only to the **first successful** one. A simple analogy: > Imagine you sent three couriers along different routes. > > - `Promise.any()` says: "whichever result **arrives successfully first** is the one I take, and the failures of the rest do not concern me". > - Only if **all** of them get lost do you hear about an error. Summary: | Property | Value | | --- | --- | | **What it does** | Returns the first **successfully fulfilled** promise | | **If all are rejected** | Returns an `AggregateError` with the reasons | | **Return type** | `Promise` | | **Similar to** | `Promise.race()`, but it ignores `reject` | | **Typical scenarios** | Fallback requests, backup data sources, redundant API calls | ### Common mistakes - **Expecting a plain error in `catch`.** What arrives is an `AggregateError`, and the concrete reasons live in `err.errors`, so `err.message` on its own explains almost nothing. - **Confusing it with `Promise.race()`.** `race()` fails on the very first rejection, while `any()` keeps waiting for a success. - **Forgetting about support.** `Promise.any()` is ES2021: very old environments need a polyfill. - **Thinking the losing requests get cancelled.** The other promises keep running and keep loading the network, real cancellation needs an `AbortController`. - **Passing an empty array.** `Promise.any([])` rejects immediately with an `AggregateError`, because there is no candidate that could succeed. - **Assuming `fetch` rejects on a server error.** A 500 response counts as success for `fetch`, so in a fallback scenario the status has to be checked by hand and the error thrown yourself.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.