retryAsyncWithJitteredBackoff
JavaScript
// Retries an async operation with capped exponential backoff and full jitter.
export async function retryAsync(fn, {
retries = 5,
baseMs = 100,
capMs = 5_000,
shouldRetry = () => true,
} = {}) {
if (!Number.isInteger(retries) || retries < 0) {
throw new RangeError('retries must be a non-negative integer');
}
for (let attempt = 0; ; attempt += 1) {
try {
return await fn(attempt); // pass the attempt number to the operation
} catch (error) {
if (attempt >= retries || !shouldRetry(error, attempt)) throw error;
const ceiling = Math.min(capMs, baseMs * 2 ** attempt);
const delayMs = Math.random() * ceiling; // full jitter
await new Promise((resolve) => setTimeout(resolve, delayMs));
}
}
}