Каждая попытка получает собственный AbortController и таймер. После ошибки запрос повторяется; maxRetries означает дополнительные повторы, то есть всего максимум maxRetries + 1 попыток.
Функция HTTP‑запроса с автоматическими повторениями и ограничением по времени
Каждая попытка получает собственный AbortController и таймер. После ошибки запрос повторяется; maxRetries означает дополнительные повторы, то есть всего максимум maxRetries + 1 попыток.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Требуется написать функцию retryFetch, принимающую следующие аргументы:
endpoint— URL, к которому будет отправлен HTTP‑запрос;maxRetries— число попыток повторить запрос в случае неудачи;requestTimeout— максимальная продолжительность ожидания ответа для каждой отдельной попытки. Функция должна выполнить запросfetchк указанномуendpointи, в случае ошибки или превышения таймаута, повторять его, пока не получит успешный ответ или не исчерпает количество попытокmaxRetries. При успешном завершении запрос должен вернуть полученные данные, преобразованные в JSON. Если после всех попыток запрос не удался, следует бросить последнюю полученную ошибку.
Ответ
Каждая попытка получает собственный AbortController и таймер. После ошибки запрос повторяется; maxRetries означает дополнительные повторы, то есть всего максимум maxRetries + 1 попыток.
async function retryFetch(endpoint, maxRetries, requestTimeout) {
if (!Number.isInteger(maxRetries) || maxRetries < 0 ||
!Number.isFinite(requestTimeout) || requestTimeout <= 0) throw new RangeError('Неверные параметры');
for (let attempt = 0; ; attempt++) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), requestTimeout);
try {
const response = await fetch(endpoint, { signal: controller.signal });
if (!response.ok) throw new Error('HTTP ' + response.status);
return await response.json();
} catch (error) {
if (attempt === maxRetries) throw error;
} finally { clearTimeout(timer); }
}
}
Таймер охватывает и чтение тела; JS-таймер не прерывает заблокированное синхронное выполнение. Здесь GET и повтор любых ошибок соответствуют упрощённому условию. В продукте отделяют временные сбои от постоянных 4xx, учитывают Retry-After и добавляют backoff; не распространяйте такую схему на неидемпотентные операции без защиты.