Обёртка fetch с автоматическим повтором при неудаче

Зафиксируйте контракт: положительное attempts — общее число попыток, -1 — явно заданный бесконечный режим. Не превращайте исчерпание обычного счётчика в бесконечные повторы.

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

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

Зафиксируйте контракт: положительное attempts — общее число попыток, -1 — явно заданный бесконечный режим. Не превращайте исчерпание обычного счётчика в бесконечные повторы.

Подробный разбор

Ответ с пояснениями

Условие

Необходимо реализовать функцию‑обёртку над fetch, которая будет автоматически повторять запрос в случае ошибки. Функция принимает количество попыток и любые остальные аргументы, передаваемые в fetch. После каждой неудачной попытки следует выполнить запрос ещё раз, пока количество оставшихся попыток не станет -1 (бесконечный режим). Пример сигнатуры функции:

async function fetchWithRetry(attempts, ...args) {
  return fetch(...args);
}

Функция должна возвращать полученный от fetch промис или бросать ошибку, если все попытки исчерпаны.

Ответ

Зафиксируйте контракт: положительное attempts — общее число попыток, -1 — явно заданный бесконечный режим. Не превращайте исчерпание обычного счётчика в бесконечные повторы.

async function fetchWithRetry(attempts, ...args) {
  if (!Number.isInteger(attempts) || (attempts !== -1 && attempts < 1)) {
    throw new RangeError('attempts: положительное целое или -1');
  }
  const signal = args[1]?.signal ?? args[0]?.signal;
  let remaining = attempts;
  for (;;) {
    if (signal?.aborted) throw signal.reason ?? new Error('Aborted');
    try {
      const response = await fetch(...args);
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      return response;
    } catch (error) {
      if (signal?.aborted || remaining === 1) throw error;
      if (remaining !== -1) remaining--;
      await new Promise(resolve => setTimeout(resolve, 1000));
    }
  }
}

Для учебного условия повторяются все ошибки, включая HTTP. В production нужны ограничения по статусам, backoff, отмена и таймаут. POST с побочными эффектами нельзя повторять без идемпотентности; одноразовый stream-body необходимо создавать заново для каждой попытки.

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

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

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

Подробнее