Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що роблять AbortController і AbortSignal?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`AbortController`** - це контролер, який створює **сигнал (`AbortSignal`)** і вміє його "смикати" (скасовувати). **Ключове:** `AbortController` - це "пульт", а `AbortSignal` - "провід", який підключається до операції (наприклад, `fetch`), щоб її можна було перервати.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке AbortController `AbortController` - це **контролер**, який створює **сигнал (**`AbortSignal`**)** і вміє його "смикати" (скасовувати). > Простіше кажучи: > `AbortController` - це "пульт", > `AbortSignal` - це "провід", який підключається до операції. --- ## Приклад ```javascript const controller = new AbortController(); const { signal } = controller; fetch('https://example.com/data', { signal }) .then(res => res.json()) .then(data => console.log('Успіх:', data)) .catch(err => { if (err.name === 'AbortError') { console.log('Запит скасовано!'); } else { console.error('Помилка:', err); } }); // Скасовуємо запит через 2 секунди setTimeout(() => controller.abort(), 2000); ``` **Що відбувається:** 1. Створюється контролер. 2. З нього дістається `signal`. 3. `signal` передається у `fetch`. 4. Через 2 секунди викликається `controller.abort()`. 5. `fetch` переривається і повертає помилку `AbortError`. --- ## Як це влаштовано всередині ### AbortController - Має методи: ```javascript controller.abort(reason?) // скасувати операцію controller.signal // посилання на сигнал ``` ### AbortSignal - Містить стан: ```javascript signal.aborted // true, якщо вже скасовано ``` - Може слухати подію: ```javascript signal.addEventListener('abort', () => console.log('Скасування!')); ``` --- ## Приклад роботи з кількома завданнями Ти можеш використовувати **один контролер** для **кількох операцій** одразу: ```javascript const controller = new AbortController(); fetch('/users', { signal: controller.signal }); fetch('/posts', { signal: controller.signal }); // скасовуємо обидві операції одразу controller.abort(); ``` Обидва запити будуть перервані. --- ## Можна вказати причину скасування ```javascript controller.abort('Ручне скасування'); signal.addEventListener('abort', e => { console.log(e.target.reason); // "Ручне скасування" }); ``` (Підтримується в сучасних браузерах і Node 18+) --- ## Використання з Promise.race для таймауту ```javascript function fetchWithTimeout(url, ms) { const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), ms); return fetch(url, { signal: controller.signal }) .finally(() => clearTimeout(timeout)); } fetchWithTimeout('/api/data', 2000) .then(r => r.json()) .then(console.log) .catch(err => { if (err.name === 'AbortError') console.log('Таймаут!'); }); ``` Зручний шаблон: скасування після завершення часу. --- ## Можна слухати скасування вручну (не лише у fetch) ```javascript function wait(ms, signal) { return new Promise((resolve, reject) => { const timeout = setTimeout(resolve, ms); signal.addEventListener('abort', () => { clearTimeout(timeout); reject(new Error('Скасовано')); }); }); } const controller = new AbortController(); wait(5000, controller.signal).catch(console.error); setTimeout(() => controller.abort(), 2000); ``` Тут `wait()` - користувацька функція, але вона вміє реагувати на `AbortSignal`, як `fetch`. --- ## Підтримка Працює в: - усіх сучасних браузерах (Chrome, Firefox, Safari, Edge) - Node.js 16.5+ (у `fetch`, `stream`, `setTimeout`) --- ## Проста аналогія > `AbortController` - це пульт керування. > > `AbortSignal` - це провід, з'єднаний із завданням. > > Коли натискаєш `abort()`, сигнал проходить по проводу і повідомляє завданню: > "Зупинись!" --- ## ПІДСУМОК | Об'єкт | Що робить | Основні властивості/методи | |---|---|---| | `AbortController` | Керує скасуванням | `.abort()`, `.signal` | | `AbortSignal` | Передається в операцію, щоб слухати скасування | `.aborted`, `.addEventListener('abort')` | | **Типова помилка** | `AbortError` - викидається при скасуванні | | | **Типові сценарії** | Скасування `fetch`, таймаути, переривання кількох завдань | |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.