whilst
whilst repeatedly executes an async task as long as a test condition returns true. The library also exports until, doWhilst, and doUntil as related loop constructs.
Best for conditional loops Use
whilstwhen you need to poll until a condition is met, retry until success, or loop while a resource is available.
Import
Section titled “Import”Root package:
import { whilst, until, doWhilst, doUntil } from "@vgerbot/async";Module subpath:
import { whilst, until, doWhilst, doUntil } from "@vgerbot/async/control-flow";Leaf subpath:
import { whilst } from "@vgerbot/async/control-flow/whilst";Quick example
Section titled “Quick example”import { whilst } from "@vgerbot/async";
let count = 0;
const handle = whilst( async () => count < 5, async (token) => { await token.sleep(100); count++; },);
await handle;console.log(count); // 5When to use
Section titled “When to use”whilst: Check condition first, then run task. Loop while condition is true.until: Check condition first, then run task. Loop until condition is true (opposite ofwhilst).doWhilst: Run task first, then check condition. Loop while condition is true.doUntil: Run task first, then check condition. Loop until condition is true.
type WhilstTest = (token: CancellableToken) => boolean | Promise<boolean>;type WhilstIteratee = (token: CancellableToken) => void | Promise<void>;
function whilst( test: WhilstTest, iteratee: WhilstIteratee, options?: CancellableOptions,): CancellableHandle<void>;
function until( test: WhilstTest, iteratee: WhilstIteratee, options?: CancellableOptions,): CancellableHandle<void>;
function doWhilst( iteratee: WhilstIteratee, test: WhilstTest, options?: CancellableOptions,): CancellableHandle<void>;
function doUntil( iteratee: WhilstIteratee, test: WhilstTest, options?: CancellableOptions,): CancellableHandle<void>;Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
test |
(token) => boolean | Promise<boolean> |
— | Condition evaluated before (or after) each iteration. Receives a CancellableToken. Can return a boolean or a Promise that resolves to a boolean. |
iteratee |
(token) => void | Promise<void> |
— | Async function executed on each iteration. Receives a CancellableToken. |
options |
CancellableOptions |
undefined |
Cancellable configuration options. |
Return value
Section titled “Return value”Returns a CancellableHandle<void> that resolves when the loop completes.
const handle = whilst(test, iteratee);
await handle;handle.cancel("No longer needed");handle.isCancelled();handle.signal;Execution model
Section titled “Execution model”whilst
Section titled “whilst”- Call
test(). If it resolves tofalse, stop. - Call
iteratee(token). - Repeat from step 1.
- Call
test(). If it resolves totrue, stop. - Call
iteratee(token). - Repeat from step 1.
doWhilst
Section titled “doWhilst”- Call
iteratee(token). - Call
test(). If it resolves tofalse, stop. - Repeat from step 1.
doUntil
Section titled “doUntil”- Call
iteratee(token). - Call
test(). If it resolves totrue, stop. - Repeat from step 1.
// Polling with whilstimport { whilst } from "@vgerbot/async";
const handle = whilst( async () => { const status = await fetch("/api/job/status").then((r) => r.json()); return status.state !== "completed"; }, async (token) => { await token.sleep(1000); // Poll every second }, { name: "jobPolling" },);
await handle;console.log("Job completed");Error handling
Section titled “Error handling”If either test or iteratee rejects, the loop stops and the handle rejects with that error.
try { await whilst( async () => true, async () => { throw new Error("iteratee failed"); }, );} catch (error) { console.log("Loop failed:", error);}Cancellation
Section titled “Cancellation”The loop checks for cancellation between iterations. Calling cancel() on the handle causes the next iteration check to throw a CancelError.
const handle = whilst( async () => true, async (token) => { await token.sleep(1000); }, { name: "infinitePoll" },);
setTimeout(() => handle.cancel("User navigated away"), 5000);
try { await handle;} catch (error) { if (error instanceof CancelError) { console.log("Loop was cancelled"); }}TypeScript tips
Section titled “TypeScript tips”The iteratee returns Promise<void> — it does not accumulate results. Use reduce or transform if you need to collect values across iterations.
// Collecting results with transform insteadimport { transform } from "@vgerbot/async";
const results = await transform( Array.from({ length: 5 }, (_, i) => i), async (acc, i, token) => { await token.sleep(10); acc.push(i * 2); }, [] as number[],);