← Усі задачіJavaScript · Senior
retry: повтор у разі помилки
Напишіть функцію retry(fn, attempts, delay). Вона викликає fn (функцію, яка повертає проміс або кидає помилку) і в разі помилки пробує знову, загалом не більше attempts разів, чекаючи delay мілісекунд між спробами.
Поверніть результат першої успішної спроби. Якщо всі спроби невдалі, відхиліть проміс помилкою останньої спроби. Синхронна помилка всередині fn теж вважається невдалою спробою.
Ctrl+Enter - запустити тести. Tab - відступ; щоб вийти з редактора клавіатурою, натисніть Esc, а потім Tab. Код зберігається в цьому браузері.
Тести (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);