Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про JavaScript: retry, error handling, async function, exponential backoff, resilience

Как реализовать повторное выполнение функции при ошибке?

Этот вопрос проверяет умение реализовывать механизм повторных попыток (retry) для обработки временных сбоев в асинхронных операциях, что критически важно для повышения отказоустойчивости приложений.

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

Повторное выполнение функции при ошибке реализуется через механизм retry, который перезапускает операцию в случае сбоя. Простейший способ — обернуть вызов функции в цикл с ограниченным количеством попыток и проверкой на успех. Для сетевых запросов часто применяют стратегию exponential backoff, где пауза между попытками увеличивается по экспоненте, чтобы снизить нагрузку на сервер. Это позволяет приложению переживать временные неполадки, такие как таймауты сети или перегрузка сервиса.

Длинный ответ

Механизм повторных попыток (retry) — это паттерн проектирования, который повышает устойчивость приложения к временным сбоям. Вместо того чтобы немедленно сообщать об ошибке, система предпринимает несколько попыток выполнить операцию, прежде чем признать её неудачной. Это особенно полезно для операций, зависящих от внешних ресурсов: сетевых запросов, подключений к базе данных или вызовов сторонних API, где сбои часто носят временный характер.

Базовый принцип реализации

Основная идея — обернуть вызов функции в цикл, который будет выполняться до тех пор, пока операция не завершится успешно или не будет исчерпан лимит попыток. Внутри цикла используется блок try/catch для перехвата исключений. При возникновении ошибки выполнение прерывается, увеличивается счётчик попыток, и после паузы цикл повторяется.

Стратегии задержки между попытками

Простая повторная попытка без задержки может усугубить проблему, например, перегрузить упавший сервер. Поэтому применяют стратегии задержки:

  • Фиксированная задержка: одинаковый интервал между всеми попытками.
  • Экспоненциальная задержка (exponential backoff): время ожидания удваивается с каждой новой попыткой (например, 1с, 2с, 4с). Это даёт системе время на восстановление.
  • Случайная оттяжка (jitter): добавление случайной компоненты к задержке, чтобы предотвратить синхронизацию множества клиентов.

Пример реализации на JavaScript

Ниже приведён пример функции-обёртки с экспоненциальной задержкой и ограничением попыток.

async function retryWithBackoff(operation, maxRetries = 3, baseDelay = 1000) {
  let lastError;
  
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      // Пытаемся выполнить переданную асинхронную операцию
      return await operation();
    } catch (error) {
      lastError = error;
      console.warn(`Attempt ${attempt} failed:`, error.message);
      
      // Если это последняя попытка — выходим из цикла
      if (attempt === maxRetries) break;
      
      // Вычисляем задержку: baseDelay * 2^(attempt-1)
      const delay = baseDelay * Math.pow(2, attempt - 1);
      // Добавляем небольшую случайность (jitter)
      const jitter = delay * 0.1 * Math.random();
      await new Promise(resolve => setTimeout(resolve, delay + jitter));
    }
  }
  
  // Если все попытки исчерпаны, пробрасываем последнюю ошибку
  throw lastError;
}

// Пример использования: функция, имитирующая ненадёжный сетевой запрос
async function fetchData() {
  const shouldFail = Math.random() > 0.5;
  if (shouldFail) throw new Error('Network timeout');
  return { data: 'Success!' };
}

// Вызов с повторными попытками
retryWithBackoff(fetchData, 3, 1000)
  .then(result => console.log('Result:', result))
  .catch(error => console.error('All attempts failed:', error));

Где и как применять

Retry-логика применяется в самых разных сценариях:

  • HTTP-клиенты и API-вызовы: для обработки статусов 5xx (ошибки сервера) или таймаутов.
  • Подключения к базам данных: при временной недоступности БД.
  • Очереди сообщений: при обработке сообщений из Kafka или RabbitMQ.
  • Фоновые задачи и cron-задания: чтобы обеспечить их завершение даже при временных сбоях.

Важно не применять retry для ошибок, которые не являются временными (например, 404 Not Found или ошибки валидации 4xx). Также следует настраивать разумные лимиты попыток и задержек, чтобы не блокировать систему надолго.

Вывод: Механизм повторных попыток — это ключевой инструмент для создания отказоустойчивых приложений. Его стоит применять для операций, где сбои вероятны, но носят временный характер, таких как сетевые запросы или взаимодействие с внешними сервисами. Использование стратегии exponential backoff с jitter делает реализацию эффективной и безопасной для распределённых систем.

  • Аватар

    Python Guru

    Sergey Filichkin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • JavaScript

    JavaScript

  • Node.js

    Node.js

Ключевые слова

#retry

#error handling

#async function

#exponential backoff

#resilience

Подпишись на Python Developer в телеграм

  • Аватар

    Python Guru

    Sergey Filichkin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.