Retries an async function upon failure with configurable backoff and retry logic.
Signature
async function retry<T>(
fn: (attempt: number) => Promise<T>,
options?: RetryOptions,
): Promise<T>
Parameters
fn
(attempt: number) => Promise<T>
required
The async function to retry. Receives the current attempt number (0-indexed).
Retry configuration options.
Maximum number of attempts.
delay
number | (attempt: number) => number
Delay between retries in milliseconds, or a function computing the delay from the attempt number (0-indexed).
shouldRetry
(error: unknown) => boolean
Predicate to decide whether to retry on a given error. If it returns false, the error is thrown immediately.
Optional AbortSignal to cancel the retry operation.
Returns
A promise that resolves with the result of the function on success.
Throws
- The last error if all attempts are exhausted
AbortError if the signal is aborted
Examples
Basic retry
import { retry } from '@temelj/async';
const result = await retry(async () => {
return await fetchData();
}, { times: 3 });
Exponential backoff
import { retry } from '@temelj/async';
const result = await retry(
async (attempt) => {
console.log(`Attempt ${attempt + 1}`);
return await fetchData();
},
{
times: 5,
delay: (attempt) => Math.pow(2, attempt) * 1000, // 1s, 2s, 4s, 8s
}
);
Conditional retry
import { retry } from '@temelj/async';
const result = await retry(
async () => {
return await fetchData();
},
{
times: 3,
shouldRetry: (error) => {
// Only retry on network errors, not 4xx errors
return error instanceof NetworkError;
},
}
);
With abort signal
import { retry } from '@temelj/async';
const controller = new AbortController();
const result = await retry(
async () => {
return await fetchData();
},
{
times: 5,
delay: 1000,
signal: controller.signal,
}
);
// Cancel retry
controller.abort();