Асинхронный JavaScriptЗапуск асинхронных функцийhard

Декоратор retry

Допустим, у нас есть асинхронная функция, которая иногда завершается успешно, а иногда нет.

Например, функция sum с вероятностью 30% считает сумму, а в остальных случаях подает с ошибкой.

function sum(a, b) { return new Promise((resolve, reject) => { setTimeout(() => { if (Math.random() < 0.3) { resolve(a + b); } else { reject("err"); } }, 500); }); } sum(3, 2).then( value => console.log(value), // 5 (с вероятностью 30%) reason => console.log(reason), // 'err' (с вероятностью 70%) );

Чтобы увеличить шансы в конечном итоге получить результат, мы хотим при неудачной попытке делать повторный вызов. Если второй раз опять вышла ошибка, запускаем еще раз. И так до первого успешного выполнения. При этом количество попыток ограничено.

Ваше задание реализовать функцию декоратор withRetry. Она принимает асинхронную функцию fn, которую мы будем вызывать несколько раз и число limit — максимальное количество вызовов.

Если за limit попыток не удалось получить ответ, результат реджектится ошибкой AggregateError с сообщением Too Many Calls и массивом ошибок, полученных в результате неудачных вызовов. Про ошибку AggregateError подробнее мы говорили в задаче any.

const enhancedSum = withRetry(sum, 4); enhancedSum(3, 2).then( value => console.log(value), // 5 (с вероятностью 76%) reason => console.log(reason.errors), // ['err1', 'err2', 'err3', 'err4'] // (с вероятностью 24%) );

Способы решения

Задачу можно решить двумя способами: через then и с помощью async/await.