Пейджер

🌍 Привет мир! 👋🏻

🌍 Привет мир! 👋🏻

Давненько не было чего-то из мира frontend. Сегодня поговорим про AbortController, но не только про использование данного инструмента в fetch, а о чем-то более специфичном.

🤔 Что это и зачем?

AbortController – глобальный класс в JavaScript для отмены операций. Позволяет легко останавливать запросы или обработчики событий, как итог идет экономя ресурсов и улучшение отзывчивости интерфейса.

⚡️ Имплементация в Fetch

const controller = new AbortController();

fetch('/data', { signal: controller.signal })
  .then(response => response.json())
  .catch(err => {
    if (err.name === 'AbortError') {
      console.log('Запрос был отменён!');
    }
  });

controller.abort();


1️⃣ Создание контроллера

В коде создаётся инстанс AbortController, который позволяет при необходимости, отменять запрос.

2️⃣ Отмена

В стороннем коде может возникнуть необходимость прервать запрос — например, если данные больше не нужны или произошла смена контекста. Для отмены запроса вызывается метод abort, который прерывает выполнение fetch.

3️⃣ Обработка ошибки

Отмена запроса вызывает исключение, которое перехватывается в catch. В блоке catch проверяется имя ошибки. если это AbortError, выполняется необходимая логика. Это помогает избежать обработки других ошибок, связанных с реальными проблемами.

‼️ Остановка одного или нескольких обработчиков:

А вы знали что третьим параметром в addEventListener можно передавать сигнал, который стриггерит удаление обработчика ?

useEffect(() => {
  const controller = new AbortController()

  window.addEventListener('scroll', handleScroll, {
    signal: controller.signal,
  })
  window.addEventListener('resize', handleResize, {
    signal: controller.signal,
  })

  return () => {
    controller.abort()
  }
}, [])


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

🛠 Запросы с автоматической отменой по таймеру:

Можно использовать AbortSignal.timeout , это статический метод, который отправляет событие прерывания по истечении определенного времени ожидания.

fetch('/slow', { signal: AbortSignal.timeout(3000) })
  .then(res => res.json())
  .catch(err => console.error('Запрос отменён: ', err));


⚙️ Комбинированная отмена

Прям редкий кейс, сам не использовал, но стоит показать и такую возможность. Если необходимо отменить операцию по нескольким сигналам, можно использовать AbortSignal.any:

const timeoutSignal = AbortSignal.timeout(5000);
const userAbortController = new AbortController();

const combinedSignal = AbortSignal.any([timeoutSignal, userAbortController.signal]);

fetch('/some-endpoint', { signal: combinedSignal })
  .catch(err => {
    if (err.name === 'AbortError') {
      console.log('Запрос отменён:', combinedSignal.reason);
    }
  });

// Пользователь вручную отменяет операцию:
userAbortController.abort('Пользователь отменил запрос');


Здесь запрос отменится, если произойдёт одно из двух событий:

- 🕑 истечёт таймаут в 5 секунд (автоматическая отмена),
- ✋ пользователь сам отменит запрос (userAbortController.abort()).

Причина отмены (combinedSignal.reason) покажет, что именно вызвало отмену.

💡 Кастомизация причин отмены

Есть возможность указывать любую причину отмены, это удобно для имплементации реакции на различные причины прерывания.

const controller = new AbortController();

controller.signal.addEventListener('abort', () => {
  console.log(controller.signal.reason);
});

controller.abort("Пользователь отменил действие");


💬 Делитесь своим мнением в комментариях👇! Если вам понравилась статья, не забудьте поставить лайк! 👍

#REACT
Медиа 1
Хотите больше таких постов?
Подпишитесь на канал и читайте продолжение в Telegram.
Подписаться на @ivanchikovitclub Открыть пост в Telegram