Skip to content

allSettled

allSettled runs multiple async tasks concurrently and resolves with an array of outcome objects after all tasks have settled. It is the cancellable equivalent of Promise.allSettled.

Best for comprehensive results Use allSettled when you want to know the outcome of every task, regardless of whether it succeeded or failed.

Root package:

import { allSettled } from "@vgerbot/async";

Module subpath:

import { allSettled } from "@vgerbot/async/control-flow";

Leaf subpath:

import { allSettled } from "@vgerbot/async/control-flow/allSettled";
import { allSettled } from "@vgerbot/async";
const handle = allSettled({},
async () => "success",
async () => { throw new Error("fail"); },
async () => 42,
);
const outcomes = await handle;
// [
// { status: "fulfilled", value: "success" },
// { status: "rejected", reason: Error("fail") },
// { status: "fulfilled", value: 42 },
// ]
  • Batch operations: Run multiple operations and collect all results, including failures.
  • Best-effort fetching: Fetch from multiple sources and use whatever succeeds.
  • Error reporting: Get a complete picture of which operations succeeded and which failed.
  • Cleanup verification: Run cleanup tasks and verify their outcomes.
function allSettled(
options: CancellableOptions<unknown[]>,
...tasks: AsyncTask<unknown>[]
): CancellableHandle<PromiseSettledResult<unknown>[]>;
Parameter Type Default Description
options CancellableOptions<unknown[]> Cancellable configuration options.
...tasks AsyncTask<T>[] Rest parameters of async tasks to execute. Each receives a CancellableToken.

Returns a CancellableHandle<PromiseSettledResult<T>[]> that resolves to an array of outcome objects.

Each outcome is either:

  • { status: "fulfilled", value: T } — task succeeded
  • { status: "rejected", reason: unknown } — task failed
const handle = allSettled({}, task1, task2, task3);
const outcomes = await handle;
handle.cancel("No longer needed");
handle.isCancelled();
handle.signal;

All tasks start concurrently and share a CancellableToken. The handle resolves only after every task has settled (either fulfilled or rejected). Results are in the same order as the input tasks.

const handle = allSettled({},
async (token) => { await token.sleep(100); return "a"; },
async (token) => { throw new Error("b failed"); },
async (token) => { await token.sleep(50); return "c"; },
);
const outcomes = await handle;
// outcomes[0] = { status: "fulfilled", value: "a" }
// outcomes[1] = { status: "rejected", reason: Error("b failed") }
// outcomes[2] = { status: "fulfilled", value: "c" }

allSettled never rejects due to task failures—it always resolves with the full set of outcomes. Individual failures are captured as { status: "rejected", reason } entries.

const outcomes = await allSettled({},
async () => "ok",
async () => { throw new Error("fail"); },
);
const successes = outcomes
.filter((o) => o.status === "fulfilled")
.map((o) => (o as PromiseFulfilledResult<string>).value);
const failures = outcomes
.filter((o) => o.status === "rejected")
.map((o) => (o as PromiseRejectedResult).reason);

Calling cancel() on the handle cancels all participating tasks. If cancelled, the handle rejects with a CancelError rather than returning partial results.

const handle = allSettled(
{ name: "batchFetch" },
...Array.from({ length: 10 }, (_, i) =>
async (token) => { await token.sleep(1000); return i; }
),
);
setTimeout(() => handle.cancel("User navigated away"), 100);
try {
await handle;
} catch (error) {
if (error instanceof CancelError) {
console.log("Batch was cancelled");
}
}

allSettled uses the standard PromiseSettledResult<T> type from the TypeScript standard library.

const outcomes = await allSettled({},
async () => 1,
async () => "hello",
);
// Type: PromiseSettledResult<number | string>[]

Use type guards to narrow the union:

for (const outcome of outcomes) {
if (outcome.status === "fulfilled") {
console.log(outcome.value); // T
} else {
console.error(outcome.reason); // unknown
}
}
  • parallel runs all tasks and rejects on first failure.
  • any resolves with the first task to fulfill.
  • race settles with the first task to complete.
  • reflect wraps a single task to always resolve.