AbortController у JavaScript: Як ефективно керувати асинхронними операціями

AbortController

Асинхронне програмування у JavaScript дозволяє створювати веб-додатки з швидким і чуйним інтерфейсом, однак управління асинхронними запитами може бути непростим завданням. Що робити, якщо потрібно припинити виконання запиту, коли він вже запущений? Наприклад, користувач переходить на іншу сторінку, а дані попереднього запиту ще не завантажилися. Саме для таких випадків у JavaScript є чудовий інструмент — AbortController.

У цій статті розглянемо, що таке AbortController, як він працює, для чого його використовують, а також розберемо реальні приклади використання.

Що таке AbortController?

AbortController — це вбудований браузерний API, що дозволяє скасовувати асинхронні операції, такі як HTTP-запити, таймери або навіть потоки даних. Він був створений, щоб ефективно керувати ресурсами та запобігати непотрібним запитам, які можуть навантажувати браузер або сервер.

AbortController має дві важливі частини:

  • AbortController: об’єкт-контролер, який створює сигнал для відміни операції.
  • AbortSignal: сигнал, який передається до асинхронної функції (наприклад, fetch) і дозволяє їй реагувати на запит про скасування.

Як працює AbortController?

Для використання AbortController треба зробити кілька простих кроків:

  1. Створити екземпляр AbortController.
  2. Передати сигнал (AbortSignal) до функції, яка може бути перервана (наприклад, fetch).
  3. Викликати метод 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(err => {
    if (err.name === 'AbortError') {
      console.log('Запит було скасовано!');
    } else {
      console.error('Інша помилка:', err);
    }
  });

// Пізніше, коли треба зупинити запит:
controller.abort();

Реальні приклади використання AbortController

1. Скасування HTTP-запиту при зміні сторінки

Уявімо, що користувач відкриває сторінку, що завантажує багато даних, але перед завершенням запиту вирішує перейти на іншу сторінку:

const controller = new AbortController();
const signal = controller.signal;

fetch('/long-request', { signal })
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => {
    if (err.name === 'AbortError') {
      console.log('Користувач перейшов на іншу сторінку.');
    }
  });

window.addEventListener('beforeunload', () => {
  controller.abort();
});

У цьому прикладі ми ефективно економимо ресурси браузера та сервера, скасовуючи непотрібні запити.

2. Таймаут для HTTP-запиту

Ще один типовий випадок – встановлення таймаута для запиту. Якщо сервер не відповідає протягом певного часу, ми можемо перервати запит:

const controller = new AbortController();
const signal = controller.signal;

const fetchTimeout = setTimeout(() => {
  controller.abort();
}, 5000); // 5 секунд таймаут

fetch('/slow-endpoint', { signal })
  .then(response => response.json())
  .then(data => {
    clearTimeout(fetchTimeout);
    console.log(data);
  })
  .catch(err => {
    if (err.name === 'AbortError') {
      console.log('Запит скасовано через таймаут.');
    } else {
      console.error(err);
    }
  });

Використання AbortController з іншими API

AbortController можна використовувати не тільки з Fetch API. Багато сучасних API браузерів підтримують його, наприклад:

  • Streams API
  • EventSource
  • Axios (з версії 0.22.0 підтримує AbortController)

Приклад з Axios:

import axios from 'axios';

const controller = new AbortController();

axios.get('/data', {
  signal: controller.signal
})
  .then(response => console.log(response.data))
  .catch(err => {
    if (axios.isCancel(err)) {
      console.log('Запит скасовано:', err.message);
    } else {
      console.error(err);
    }
  });

// Скасування запиту через 3 секунди:
setTimeout(() => {
  controller.abort();
}, 3000);

Переваги використання AbortController

  • Зменшення навантаження: дозволяє ефективно керувати ресурсами та зменшувати кількість зайвих запитів до сервера.
  • Покращення UX: дозволяє швидше реагувати на дії користувача.
  • Економія трафіку: зменшує кількість непотрібних мережевих з’єднань.

Коли НЕ варто використовувати AbortController?

Хоча AbortController дуже корисний, не варто зловживати його використанням. Не потрібно скасовувати всі запити поспіль, оскільки це може спричинити зайву складність вашого коду. Варто використовувати AbortController, коли це дійсно необхідно, наприклад, для управління таймаутами, скасування великих запитів, або коли користувач активно взаємодіє з інтерфейсом, що змінюється швидко.

Висновок

AbortController – це сучасний і зручний інструмент для контролю асинхронних запитів у JavaScript. Завдяки його використанню ви можете значно підвищити продуктивність вашого веб-додатку, покращити користувацький досвід, та ефективно керувати ресурсами.

Тепер ви точно знаєте, що робити з тими набридливими запитами, які тривають надто довго або перестають бути актуальними. Просто використовуйте AbortController і будьте певні – ваш код стане чіткішим, а ваші користувачі – щасливішими!