JavaScript AbortController.signal — сигнал скасування


Властивість signal — це сигнал скасування, який передають туди, що має вміти скасовуватись.

автор: NagarD

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

Один сигнал можна віддати скільком завгодно місцям: у fetch, у addEventListener({ signal }), у ResizeObserver. Один виклик abort() вимкне все це разом.

Саме тому це найнадійніший спосіб прибрати за собою: не треба тримати посилання на кожну функцію-обробник, щоб потім її зняти.

У сигналу є aborted (чи вже скасовано) і подія abort — на неї можна підписатись, щоб виконати власне прибирання.

Окремо є AbortSignal.timeout(ms) — готовий сигнал, що скасовується сам за таймаутом.

автор: NagarD

Порада

Компонент, що навішує кілька обробників, має тримати один контролер. У методі знищення — abort(), і жодного забутого обробника не лишиться.

автор: NagarD

Переглядачі

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

Приклади

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

Один сигнал знімає всі обробники компонента одразу.

class Widget {
    constructor() {
        this.controller = new AbortController();
        const { signal } = this.controller;

        this.onResize = () => console.log('resize');
        this.onScroll = () => console.log('scroll');
        this.onKey = () => console.log('keydown');

        // усі обробники слухають один сигнал
        window.addEventListener('resize', this.onResize, { signal });
        window.addEventListener('scroll', this.onScroll, { signal });
        document.addEventListener('keydown', this.onKey, { signal });
    }

    destroy() {
        // один рядок знімає все
        this.controller.abort();
    }
}

const widget = new Widget();
widget.destroy();
console.log('Обробники знято одним abort()');

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

Коментарі

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

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

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

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

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

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

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

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

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

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

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