Необходимо реализовать функцию retry, которая может принимать в себя 2 параметра:
асинхронная функция;
config: { count: number, delay: (count) => number }.
Если асинхронная функция возвращает промис в статусе rejected, то необходимо перезапустить данную функцию config.count раз с задержкой в config.delay мс, пока промис не перейдёт в статус fulfilled либо не закончится количество возможных попыток config.count. Функция retry должна возвращать промис.
Решение
Оптимальное решение
async function retry(asyncFn, config) { const { count, delay } = config; for (let attempt = 0; attempt <= count; attempt++) { try { // Пытаемся выполнить асинхронную функцию const result = await asyncFn(); return result; // Если успешно, возвращаем результат } catch (error) { // Если это последняя попытка, пробрасываем ошибку if (attempt === count) { throw error; } // Вычисляем задержку для текущей попытки const delayTime = delay(attempt); // Ждем перед следующей попыткой await new Promise((resolve) => setTimeout(resolve, delayTime)); } }}
Альтернативное решение (рекурсивное)
// Создает дополнительные стеки вызововasync function retry(asyncFn, config, currentAttempt = 0) { try { // Пытаемся выполнить функцию const result = await asyncFn(); return result; } catch (error) { // Проверяем, остались ли попытки if (currentAttempt >= config.count) { throw new Error('Retry limit has been reached', { cause: error }); } // Вычисляем задержку const delayTime = config.delay(currentAttempt); // Ждем и рекурсивно вызываем retry await new Promise((resolve) => setTimeout(resolve, delayTime)); return retry(asyncFn, config, currentAttempt + 1); }}