← Wszystkie zadaniaJavaScript · Senior
retry: ponawianie przy błędzie
Napisz funkcję retry(fn, attempts, delay). Wywołuje ona fn (funkcję, która zwraca obietnicę lub rzuca błąd) i przy błędzie próbuje ponownie, łącznie nie więcej niż attempts razy, czekając delay milisekund między próbami.
Zwróć wynik pierwszej udanej próby. Jeśli wszystkie próby się nie powiodą, odrzuć obietnicę błędem z ostatniej. Synchroniczny wyjątek w fn też liczy się jako nieudana próba.
Ctrl+Enter uruchamia testy. Tab robi wcięcie; aby wyjść z edytora klawiaturą, naciśnij Esc, a potem Tab. Kod zapisuje się w tej przeglądarce.
Testy (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);