JavaScript AbortController — скасування запиту fetch
AbortController дозволяє скасувати запит fetch, обробник події чи будь-яку операцію, яка вміє слухати сигнал скасування.
Загальний опис
Довгий час запит, який пішов у мережу, скасувати було неможливо: користувач уже пішов з іншої сторінки, а відповідь усе одно приїжджала й перезаписувала свіжі дані.
Контролер видає сигнал (controller.signal), який передається в fetch. Виклик controller.abort() обриває запит, і той падає з помилкою на ім'я AbortError.
Класичний випадок — пошук із підказками: кожне нове натискання клавіші має обірвати попередній, ще не завершений запит. Інакше відповіді приходять урозбивку й перемагає та, що приїхала останньою, а не та, що відповідає останньому запиту.
автор: NagarD
- Порада
-
Той самий сигнал можна віддати в
автор: NagarDaddEventListener({ signal })— і одинabort()зніме всі обробники відразу. Це найкоротший спосіб прибрати за собою. - Нотатка
-
Скасований запит кидає помилку.
автор: NagarDAbortError— це не збій, а очікуваний результат, тож уcatchйого варто відрізняти від справжніх помилок мережі.
Синтаксис
const controller = new AbortController();\nfetch(url, { signal: controller.signal });
властивості
| Властивість | Опис |
|---|---|
| signal | Сигнал, який передається операції для скасування. |
методи
| Метод | Опис |
|---|---|
| abort | Скасовує всі операції з цим сигналом. |
Переглядачі
| Переглядач | ||||||
|---|---|---|---|---|---|---|
| AbortController | 66+ | 57+ | 12.1+ | 53+ | 16+ | - |
| Переглядач | ||||
|---|---|---|---|---|
| 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));
Коментарі
Коментарів ще немає — будьте першим!