Когда вы отправляете асинхронный запрос — особенно через fetch
— бывает важно иметь возможность его отменить. Например, если пользователь ушёл со страницы, переключил вкладку или выполнил другое действие, которое делает запрос больше неактуальным. Если такие запросы не останавливать, они продолжают работать в фоне, потребляют ресурсы и могут привести к утечкам памяти или ошибкам, особенно если в ответе вы потом обновляете уже несуществующий интерфейс.
Для решения этой задачи в браузере появился AbortController
. Он доступен в статусе «Widely Available» с 25 сентября 2021 года, что означает — поддерживается всеми современными браузерами и безопасен для использования в продакшене.
Как это работает
🚀 Сегодня вам бесплатно доступен тренажёр по HTML и CSS.
Принцип простой: вы создаёте объект AbortController
, получаете его сигнал (signal
) и передаёте его в запрос — например, в fetch
. Когда нужно отменить запрос, просто вызываете метод abort()
у контроллера.
Вот как это выглядит в реальном коде:
const controller = new AbortController();
const signal = controller.signal;
fetch('https://api.example.com/data', { signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(error => {
if (error.name === 'AbortError') {
console.log('Запрос отменён');
} else {
console.error('Ошибка', error);
}
});
// чтобы отменить запрос
controller.abort();
На первый взгляд это может показаться избыточным, но на практике AbortController
помогает в десятках реальных сценариев: отменить автодополнение при быстрой печати, прекратить загрузку данных при переходе на другую страницу, ограничить длительность запроса с таймером и многое другое.
Стоит отметить, что если вы отмените запрос, fetch
не вызовет then
, а сразу перейдёт в catch
, где вы можете отловить ошибку с именем AbortError
. Это и есть способ отличить отмену от других типов сбоев — например, сетевых или серверных ошибок.
AbortController
особенно удобен, если вы работаете с async/await
. В этом случае структура остаётся такой же, только используется try...catch
, чтобы перехватывать отмену:
try {
const response = await fetch(url, { signal });
const data = await response.json();
console.log(data);
} catch (error) {
if (error.name === 'AbortError') {
console.log('Запрос отменён');
} else {
throw error;
}
}
Этот механизм универсален и работает не только с fetch
, но и с другими веб-API, которые поддерживают передачу AbortSignal
. Например, с ReadableStream
, navigator.bluetooth
, DOMParser
, setTimeout
(в будущем) и другими.
В целом AbortController
— это важный инструмент современного фронтенда. Он помогает писать стабильный, безопасный и управляемый код, особенно там, где происходит много взаимодействий и сетевых операций.
Больше обзоров веб-функций — в телеграм-канале HTML Academy.
Нашли ошибку или опечатку? Напишите нам.