JavaScript AbortController — скасування запиту fetch


AbortController дозволяє скасувати запит fetch, обробник події чи будь-яку операцію, яка вміє слухати сигнал скасування.

автор: NagarD

Загальний опис

Довгий час запит, який пішов у мережу, скасувати було неможливо: користувач уже пішов з іншої сторінки, а відповідь усе одно приїжджала й перезаписувала свіжі дані.

Контролер видає сигнал (controller.signal), який передається в fetch. Виклик controller.abort() обриває запит, і той падає з помилкою на ім'я AbortError.

Класичний випадок — пошук із підказками: кожне нове натискання клавіші має обірвати попередній, ще не завершений запит. Інакше відповіді приходять урозбивку й перемагає та, що приїхала останньою, а не та, що відповідає останньому запиту.

автор: NagarD

Порада

Той самий сигнал можна віддати в addEventListener({ signal }) — і один abort() зніме всі обробники відразу. Це найкоротший спосіб прибрати за собою.

автор: NagarD
Нотатка

Скасований запит кидає помилку. AbortError — це не збій, а очікуваний результат, тож у catch його варто відрізняти від справжніх помилок мережі.

автор: NagarD

Синтаксис

const controller = new AbortController();\nfetch(url, { signal: controller.signal });

властивості

Властивість Опис
signal Сигнал, який передається операції для скасування.

методи

Метод Опис
abort Скасовує всі операції з цим сигналом.

Переглядачі

Підтримка: стаціонарні переглядачі
Переглядач Google Chrome Mozilla Firefox Apple Safari Opera Microsoft EDGE Microsoft Internet Explorer
AbortController 66+ 57+ 12.1+ 53+ 16+ -
Підтримка: мобільні переглядачі
Переглядач Mobile Google Android Mobile Google Chrome Mobile Mozilla Firefox Mobile Apple Safari
AbortController 66+ yes yes 12.2+

Приклади

+ запропонувати свій приклад у пісочниці

Пошук, що обриває попередній запит, і запит із таймаутом.

HTML

<input id="search" type="search" placeholder="Пошук…">

JS

const input = document.getElementById('search');

let controller;

input.addEventListener('input', async () => {
    // обриваємо попередній, ще не завершений запит
    controller?.abort();
    controller = new AbortController();

    try {
        const response = await fetch('/search?q=' + input.value, {
            signal: controller.signal,
        });
        console.log('Результати:', await response.json());
    } catch (error) {
        // скасування — не збій, мовчимо
        if (error.name !== 'AbortError') {
            console.log('Запит не пройшов:', error.message);
        }
    }
});

// запит із таймаутом у 5 секунд
fetch('/api/slow', { signal: AbortSignal.timeout(5000) })
    .catch(error => console.log('slow-запит:', error.name));
автор: NagarD

Коментарі

Коментарів ще немає — будьте першим!

Відповідь для

Увійдіть — коментар з'явиться одразу, без капчі й очікування перевірки.

Пропозиція правки

Ваша версія — : після перевірки замінить чинну. Нова порада чи нотатка — з'явиться на сторінці після перевірки.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Ваша версія секції «»: після перевірки замінить чинну.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Ваша версія опису «»: після перевірки замінить чинну.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Зворотний зв'язок
Вхід