Повтор асинхронной операции — это паттерн, при котором неудачно завершившаяся асинхронная операция автоматически выполняется повторно через определенные промежутки времени. Это особенно полезно при работе с сетевыми запросами, которые могут временно завершаться ошибкой из-за проблем с сетью, сервером или перегрузки.
Основные подходы:
Реализация повтора асинхронных операций — важная техника для создания надежных веб-приложений. Она позволяет автоматически восстанавливаться от временных сбоев без участия пользователя.
При реализации повтора необходимо учитывать несколько важных параметров:
// Базовая функция повтора
async function retryOperation(operation, maxRetries = 3) {
for (let i = 0; i <= maxRetries; i++) {
try {
return await operation();
} catch (error) {
if (i === maxRetries) throw error;
// Пауза перед следующей попыткой
await delay(1000 * Math.pow(2, i));
}
}
}Одинаковый интервал между всеми попытками:
function fixedDelayRetry(operation, retries, delayMs) {
// Повтор с фиксированной задержкой
}Интервал увеличивается в геометрической прогрессии:
// Задержки: 1s, 2s, 4s, 8s...
const delay = 1000 * Math.pow(2, attempt);Добавление случайности для распределения нагрузки:
// Дрожание уменьшает конкуренцию
const jitter = Math.random() * maxJitter;async function fetchWithRetry(url, options = {}) {
const { maxRetries = 3, retryDelay = 1000 } = options;
for (let i = 0; i <= maxRetries; i++) {
try {
const response = await fetch(url);
if (!response.ok) throw new Error('Request failed');
return response;
} catch (error) {
if (i === maxRetries) throw error;
await new Promise(resolve =>
setTimeout(resolve, retryDelay * Math.pow(2, i))
);
}
}
}function smartRetry(operation, config) {
const {
maxRetries = 3,
retryableErrors = ['NetworkError', 'TimeoutError']
} = config;
// Повтор только для определенных ошибок
}// ❌ Может привести к блокировке
while (true) {
try {
await operation();
break;
} catch (error) {
// Нет ограничения попыток
}
}
// ✅ С ограничением попыток
for (let i = 0; i < maxRetries; i++) {
// Логика повтора
}// ❌ Повтор даже фатальных ошибок
if (error.status === 404) {
// Ресурс не существует, повтор бесполезен
}
// ✅ Повтор только временных ошибок
if (error.status >= 500 || error.status === 429) {
// Серверные ошибки и ограничение частоты
}Реализация повтора работает во всех современных средах JavaScript, включая браузеры и Node.js.
Реализация повтора асинхронных операций — важный паттерн для создания надежных веб-приложений, который помогает справляться с временными сетевыми проблемами и серверными ошибками без участия пользователя.
Какой будет результат выполнения этого кода и как его улучшить?
async function unreliableOperation() {
if (Math.random() < 0.7) {
throw new Error('Network error');
}
return 'Success';
}
async function retry(func, times) {
try {
return await func();
} catch (error) {
if (times <= 0) throw error;
return retry(func, times - 1);
}
}
retry(unreliableOperation, 3);Ответ: Результат зависит от случайного фактора, но в большинстве случаев будет ошибка “Network error”, так как отсутствует задержка между попытками.
Проблемы в коде:
Улучшенная версия:
async function improvedRetry(func, maxRetries = 3) {
for (let i = 0; i <= maxRetries; i++) {
try {
return await func();
} catch (error) {
// Повтор только при достижении максимального количества попыток
if (i === maxRetries) throw error;
// Экспоненциальная задержка с дрожанием
const delay = 1000 * Math.pow(2, i);
const jitter = Math.random() * 500;
await new Promise(resolve =>
setTimeout(resolve, delay + jitter)
);
}
}
}Объяснение: Улучшенная версия добавляет экспоненциальную задержку и дрожание, что предотвращает одновременные повторы от множества клиентов и уменьшает нагрузку на сервер. Также она предоставляет более предсказуемое поведение и лучшую обработку ошибок.
Хотите больше статей для подготовки к собеседованиям? Подписывайтесь на EasyAdvice, добавляйте сайт в закладки и совершенствуйтесь каждый день 💪