AbortController — это встроенный в JavaScript механизм для отмены асинхронных операций. Он позволяет создать сигнал отмены, который можно передать в асинхронные операции (fetch, setTimeout и др.), чтобы прервать их выполнение. Это особенно полезно для отмены HTTP-запросов, таймеров и других длительных операций.
Основные компоненты:
AbortController — это стандартный API в JavaScript, предназначенный для отмены асинхронных операций. Он появился как решение проблемы отсутствия универсального способа отмены промисов и асинхронных операций в языке.
AbortController создает сигнал отмены, который можно передать в асинхронные операции:
const controller = new AbortController();
const { signal } = controller;
// Передаем сигнал в асинхронную операцию
fetch('/api/data', { signal });
// Отменяем операцию
controller.abort();Самый распространенный случай использования:
const controller = new AbortController();
fetch('/api/long-operation', {
signal: controller.signal
})
.then(response => response.json())
.catch(error => {
if (error.name === 'AbortError') {
console.log('Запрос отменен');
}
});
// Отмена запроса
controller.abort();Можно отменять таймеры с помощью AbortController:
function delay(ms, signal) {
return new Promise((resolve, reject) => {
const timeoutId = setTimeout(resolve, ms);
// Слушаем сигнал отмены
signal.addEventListener('abort', () => {
clearTimeout(timeoutId);
reject(new DOMException('Операция отменена', 'AbortError'));
});
});
}function fetchWithTimeout(url, timeoutMs) {
const controller = new AbortController();
// Отмена по таймауту
const timeoutId = setTimeout(() => {
controller.abort();
}, timeoutMs);
return fetch(url, { signal: controller.signal })
.finally(() => clearTimeout(timeoutId));
}const controller = new AbortController();
// При переходе отменяем все запросы
window.addEventListener('beforeunload', () => {
controller.abort();
});
fetch('/api/data', { signal: controller.signal });const controller = new AbortController();
const { signal } = controller;
// Проверяем, отменен ли сигнал
if (signal.aborted) {
console.log('Операция уже отменена');
}signal.addEventListener('abort', () => {
console.log('Операция отменена');
});// ❌ Игнорируем ошибки отмены
fetch('/api/data', { signal })
.then(response => console.log(response));
// ✅ Правильно обрабатываем ошибки
fetch('/api/data', { signal })
.then(response => console.log(response))
.catch(error => {
if (error.name === 'AbortError') {
// Ожидаемая отмена, не ошибка
console.log('Запрос отменен');
} else {
// Реальная ошибка
console.error('Ошибка запроса:', error);
}
});Вызов abort() на уже завершенных операциях не вызывает ошибок, но и не имеет эффекта.
AbortController поддерживается всеми современными браузерами. Для старых браузеров требуется полифил.
AbortController — это мощный инструмент для управления асинхронными операциями, позволяющий эффективно отменять запросы и освобождать ресурсы.
Что произойдет при выполнении этого кода и как его улучшить?
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal })
.then(response => response.json())
.then(data => console.log(data));
// Через 2 секунды отменяем
setTimeout(() => {
controller.abort();
}, 2000);Ответ: При выполнении этого кода:
/api/datacontroller.abort()Улучшенная версия:
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(error => {
if (error.name === 'AbortError') {
console.log('Запрос был отменен');
} else {
console.error('Ошибка запроса:', error);
}
});
// Через 2 секунды отменяем
setTimeout(() => {
controller.abort();
}, 2000);Объяснение:
Важно понимать, что AbortController — это не мгновенная отмена, а сигнал, который асинхронные операции могут проверять и реагировать на него соответствующим образом.
Хотите больше статей для подготовки к собеседованиям? Подписывайтесь на EasyAdvice, добавляйте сайт в закладки и совершенствуйтесь каждый день 💪