any
any runs multiple async tasks concurrently and resolves with the first one to fulfill. If all tasks reject, it rejects with an AggregateError. It is the cancellable equivalent of Promise.any.
Best for first success Use
anywhen you have multiple fallback sources and want the first successful result.
Import
Section titled “Import”Root package:
import { any } from "@vgerbot/async";Module subpath:
import { any } from "@vgerbot/async/control-flow";Leaf subpath:
import { any } from "@vgerbot/async/control-flow/any";Quick example
Section titled “Quick example”import { any } from "@vgerbot/async";
const handle = any({}, async (token) => { const res = await token.wrap(fetch("https://api1.example.com/data")); if (!res.ok) throw new Error("api1 down"); return res.json(); }, async (token) => { const res = await token.wrap(fetch("https://api2.example.com/data")); if (!res.ok) throw new Error("api2 down"); return res.json(); },);
const data = await handle; // First successful responseWhen to use any
Section titled “When to use any”- Redundant sources: Query multiple API endpoints and use the first that responds successfully.
- Fallback strategies: Try multiple approaches and use whichever works first.
- Best-effort operations: Attempt several alternatives, succeeding if any one works.
- Cancellable batches: Cancel remaining tasks once one succeeds.
function any( options: CancellableOptions, ...tasks: AsyncTask<unknown>[]): CancellableHandle<unknown>;Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
options |
CancellableOptions |
— | Cancellable configuration options. |
...tasks |
AsyncTask<T>[] |
— | Rest parameters of async tasks to execute. Each receives a CancellableToken. |
Return value
Section titled “Return value”Returns a CancellableHandle<T> that resolves with the first task to fulfill, or rejects with an AggregateError if all tasks reject.
const handle = any({}, task1, task2);
const result = await handle;handle.cancel("No longer needed");handle.isCancelled();handle.signal;Execution model
Section titled “Execution model”All tasks start concurrently and share a CancellableToken. The handle resolves as soon as the first task fulfills. Remaining tasks receive a cancellation signal.
const handle = any({}, async (token) => { await token.sleep(100); throw new Error("fail"); }, async (token) => { await token.sleep(200); return "success"; }, async (token) => { await token.sleep(500); return "also success"; },);
// Resolves with "success" after 200ms// First task's rejection is ignored// Third task is cancelledError handling
Section titled “Error handling”If all tasks reject, the handle rejects with an AggregateError containing all rejection reasons.
try { await any({}, async () => { throw new Error("fail1"); }, async () => { throw new Error("fail2"); }, );} catch (error) { if (error instanceof AggregateError) { console.log("All tasks failed:", error.errors); }}Cancellation
Section titled “Cancellation”Calling cancel() on the handle cancels all participating tasks.
const handle = any({ name: "anyOperation" }, async (token) => { await token.sleep(5000); return "result"; },);
setTimeout(() => handle.cancel("User cancelled"), 100);TypeScript tips
Section titled “TypeScript tips”any is generic over T. All tasks must return the same type.
const handle = any({}, async () => 1, async () => 2,);
const result = await handle; // numberRelated APIs
Section titled “Related APIs”racesettles with the first task to complete (fulfill or reject).allSettledwaits for all tasks and collects all outcomes.parallelruns all tasks and collects all results.tryEachtries tasks sequentially until one succeeds.