Retry-with-backoff is a real-world async pattern (flaky network calls) and a clean recursion-over-promises question.
Try fn. On rejection, either give up (out of retries → rethrow) or wait, then recurse with one fewer retry and a doubled delay. Doubling is exponential backoff — it stops a struggling server from getting hammered.
Math.min(delay * 2, maxDelay).shouldRetry(err) predicate.AbortSignal and reject early if it fires.Write the recursive version, then add a maxDelay cap and random jitter.
function retry(fn, retries = 3, delay = 100) { // fn returns a Promise; resolve on success, give up after `retries` } let n = 0; retry(() => (++n < 3 ? Promise.reject('fail') : Promise.resolve('ok'))) .then(console.log); // "ok" on the 3rd attempt
Test Code
Enter JavaScript that runs after your solution. It should return a value or a Promise.