← All tasksJavaScript · Senior
retry: retry on failure
Write a function retry(fn, attempts, delay). It calls fn (a function that returns a promise or throws) and on failure tries again, up to attempts times in total, waiting delay milliseconds between attempts.
Return the result of the first successful attempt. If every attempt fails, reject with the error from the last one. A synchronous throw inside fn also counts as a failed attempt.
Ctrl+Enter runs the tests. Tab indents; to leave the editor with the keyboard, press Esc and then Tab. Your code is saved in this browser.
Tests (5)
const f = fn(async () => 'ok'); expect(await retry(f, 3, 10)).toBe('ok'); expect(f).toHaveBeenCalledTimes(1);
let n = 0; const f = fn(async () => { n++; if (n < 3) throw new Error('fail ' + n); return n; }); expect(await retry(f, 5, 10)).toBe(3); expect(f).toHaveBeenCalledTimes(3);
const f = fn(async () => { throw new Error('nope ' + f.calls.length); }); await expect(retry(f, 3, 5)).rejects.toThrow('nope 3'); expect(f).toHaveBeenCalledTimes(3);
const f = fn(() => { throw new Error('sync'); }); await expect(retry(f, 2, 5)).rejects.toThrow('sync'); expect(f).toHaveBeenCalledTimes(2);
let n = 0; const f = async () => { n++; if (n === 1) throw new Error('x'); return 'done'; }; const started = Date.now(); expect(await retry(f, 2, 60)).toBe('done'); expect(Date.now() - started >= 50).toBe(true);