poll

import { poll } from "jsr:@ende/async";

function

async function poll<T>(fn: () => T, isDone: (result: Awaited<T>) => boolean, options: PollOptions = [UNSUPPORTED]): Promise<Awaited<T>>

Repeatedly calls a function until a condition is met, then returns the result.

This is useful for polling external APIs that don't provide push notifications. The function is called repeatedly with interval milliseconds between each call until isDone returns true, at which point the result is returned.

fn: () => T

The function to poll. Can be sync or async.

isDone: (result: Awaited<T>) => boolean

A predicate that returns true when polling should stop.

options: PollOptions = [UNSUPPORTED]

Additional options.

Returns

The result of fn when isDone returns true.

Example: Polling a payment status with deadline

import { poll } from "@ende/async/poll";
import { deadline } from "@ende/async/deadline";

async function getPaymentStatus(id: string): Promise<{ status: string }> {
  // Fetch payment status from API
  return { status: "pending" };
}

const result = await deadline(
  poll(
    () => getPaymentStatus("payment-123"),
    (payment) => payment.status !== "pending",
    { interval: 1000 },
  ),
  30_000, // 30 second timeout
);

Example: Using AbortSignal for timeout

import { poll } from "@ende/async/poll";

const result = await poll(
  () => fetch("https://api.example.com/status").then((r) => r.json()),
  (data) => data.completed === true,
  { signal: AbortSignal.timeout(30_000) },
);

Source