Реализовать fetchRetry с ограниченным числом повторов и задержкой
Реализуйте fetchRetry(url, retries, delay), использующую Fetch API и повторяющую при сбое. Требования: резолвить Response при первом успехе; при неудачной попытке подождать delay мс, затем повторить; сдаться после retries попыток и отклониться с последней ошибкой. Считать сетевую ошибку (отклонённый fetch) сбоем. Не повторять вечно; общее число попыток должно быть ограничено.
function fetchRetry(url, retries, delay) {
// ваш код здесь
}
Допишите реализацию.
Оберните попытку в рекурсивный (или циклический) помощник. try { return await fetch(url); } catch (err): если retries <= 0 — пробросить последнюю ошибку; иначе await таймера на delay мс (промис вокруг setTimeout) и рекурсия с retries - 1.
- ✗Цикл без счётчика, повторяющий вечно на постоянно падающем URL
- ✗Забыть
awaitтаймера задержки, из-за чего повторы идут подряд - ✗Проглотить последнюю ошибку вместо отклонения по исчерпании повторов
- →Как добавить экспоненциальный backoff вместо фиксированной задержки?
- →Почему стоит повторять лишь на определённых кодах статуса, а не на каждом сбое?
Решение
Рекурсивная попытка с уменьшением счётчика и ожиданием между повторами.
const wait = (ms) => new Promise((r) => setTimeout(r, ms)); // промис вокруг setTimeout
async function fetchRetry(url, retries, delay) {
try {
return await fetch(url); // первый успех резолвит сразу
} catch (err) {
if (retries <= 0) throw err; // повторы исчерпаны → последняя ошибка
await wait(delay); // подождать перед повтором
return fetchRetry(url, retries - 1, delay);
}
}
Как это работает
Каждая попытка await fetch(url); при успехе Response возвращается немедленно. При отклонении (сетевая ошибка) проверяем счётчик: при нуле пробрасываем последнюю ошибку, иначе ждём delay мс и рекурсируем с retries - 1. Это ограничивает общее число попыток и завершается отказом с последней ошибкой, а не бесконечным циклом.