Функция HTTP‑запроса с автоматическими повторениями и ограничением по времени

Каждая попытка получает собственный AbortController и таймер. После ошибки запрос повторяется; maxRetries означает дополнительные повторы, то есть всего максимум maxRetries + 1 попыток.

Короткий ответ

Что ответить на собеседовании

Каждая попытка получает собственный 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; не распространяйте такую схему на неидемпотентные операции без защиты.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

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

Подробнее