Promise.allSettled()
Waits for every promise to settle and reports each outcome without ever rejecting.
Promise.allSettled(iterable)- Added in JavaScript ES2020
Parameters
| Parameter | Type | Description |
|---|---|---|
$iterable | Iterable | An iterable, such as an Array, of promises. Values are awaited, so other thenables are resolved too; non-thenables are passed through as-is. |
Return value
PromiseA Promise that fulfills with an array of outcome objects in input order, regardless of completion order. It is already fulfilled if the iterable is empty. Each object has status "fulfilled" with a value property, or status "rejected" with a reason property.
Errors
TypeError if the argument is not iterable.
Promise.allSettled() is the combinator for when failures are data, not disasters. It waits for every input to settle and then fulfills with one record per input, in input order.
The record shape
Each entry is a plain object with a status of "fulfilled" or "rejected". Fulfilled entries carry a value; rejected entries carry a reason. The other property is absent, not undefined, so branch on status rather than checking for the presence of value — a promise that legitimately fulfills with undefined would fool that test.
When to reach for it
Batch jobs where you want a report: upload twelve files and tell the user which three failed; ping five mirrors and rank the ones that answered; run a suite of independent checks. Anywhere Promise.all()'s fail-fast would throw away results you already paid for.
What trips people up
It never rejects, so a try/catch or .catch() around it is dead code — the errors are inside the array, and it is on you to inspect them. Forgetting that turns a batch of silent failures into a batch that looks like a success.
Example
When to use it
- Upload a batch of files and report exactly which ones failed
- Run independent health checks and summarise the results
- Retry only the failed items from a batch on a second pass
- Collect results from several sources where any subset is still useful
Frequently asked questions
When should I use allSettled instead of Promise.all?
When partial results are still useful and you want to know which items failed. Promise.all throws away every result the moment one input rejects; allSettled always returns the full picture.
Why doesn't my catch block run after Promise.allSettled?
Because allSettled never rejects — failures are reported as records with status "rejected" inside the fulfillment array. Inspect those records instead of relying on catch.
How do I get just the successful values?
Filter the array on status and map to value: results.filter(r => r.status === "fulfilled").map(r => r.value).
More examples
Partition into successes and failures
Filtering on status is the standard way to split a batch. Promise.all would have rejected here and discarded both successful values; allSettled keeps them and lets you report an accurate 2-of-4 summary.
const jobs = [
Promise.resolve("a"),
Promise.reject(new Error("e1")),
Promise.resolve("b"),
Promise.reject(new Error("e2")),
];
const settled = await Promise.allSettled(jobs);
const ok = settled.filter((r) => r.status === "fulfilled").map((r) => r.value);
const bad = settled.filter((r) => r.status === "rejected").map((r) => r.reason.message);
console.log("succeeded:", ok);
console.log("failed:", bad);
console.log(`${ok.length}/${settled.length} jobs completed`);It really never rejects
Even with every input rejecting, the combined promise fulfills. The final line prints ["status", "reason"] — there is no value key at all on a rejected record, which is why you should branch on status rather than test for value.
console.log(await Promise.allSettled([]));
const r = await Promise.allSettled([
Promise.reject(new Error("x")),
Promise.reject(new Error("y")),
]);
console.log(r.every((x) => x.status === "rejected"));
console.log(Object.keys(r[0]));
Discussion