JavaScript Worker — обчислення у фоновому потоці


Worker (у перекладі — робітник) виконує JavaScript у окремому потоці, не блокуючи сторінку.

автор: NagarD

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

JavaScript у браузері однопотоковий: важкий цикл заморожує геть усе — анімації стають, кнопки не натискаються, сторінка «не відповідає».

Робітник виносить обчислення вбік. Це окремий файл зі своїм скриптом, який живе паралельно й спілкується з головним потоком повідомленнями: postMessage() туди, onmessage назад.

Ціна — ізоляція. У робітника немає доступу до DOM, до document і до window: він не може ані прочитати сторінку, ані щось на ній намалювати. Його справа — рахувати й віддати результат.

Дані між потоками копіюються, а не поділяються. Тобто передати гігантський масив теж не безкоштовно (хоч для ArrayBuffer є передача без копіювання).

автор: NagarD

Порада

Ознака, що потрібен робітник: інтерфейс підвисає на секунду й більше. Розбір великого JSON, обробка зображення, шифрування — типові кандидати.

автор: NagarD

Синтаксис

const worker = new Worker("worker.js");

методи

Метод Опис
postMessage Надсилає повідомлення воркеру.
terminate Негайно зупиняє воркер.

властивості

Властивість Опис
onmessage Обробник повідомлень від воркера.
onerror Обробник помилок воркера.

Переглядачі

Підтримка: стаціонарні переглядачі
Переглядач Google Chrome Mozilla Firefox Apple Safari Opera Microsoft EDGE Microsoft Internet Explorer
Worker 4+ 3.5+ 4+ 11.5+ 12+ 10+
Підтримка: мобільні переглядачі
Переглядач Mobile Google Android Mobile Google Chrome Mobile Mozilla Firefox Mobile Apple Safari
Worker 4.4+ yes yes 5+

Приклади

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

Важкий підрахунок, який не морозить сторінку.

HTML

<button id="run">Порахувати</button>
<p id="out">Інтерфейс лишається живим</p>

JS

// --- worker.js (окремий файл) ---
// self.onmessage = event => {
//     let sum = 0;
//     for (let i = 0; i < event.data; i++) sum += i;
//     self.postMessage(sum);
// };

// --- головний потік ---
const worker = new Worker('/worker.js');

document.getElementById('run').addEventListener('click', () => {
    // сторінка не завмре: рахує інший потік
    worker.postMessage(1e9);
});

worker.onmessage = event => {
    document.getElementById('out').textContent = 'Сума: ' + event.data;
};

worker.onerror = error => console.error(error.message);

// коли більше не потрібен
// worker.terminate();
автор: NagarD

Коментарі

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

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

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

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

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

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

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

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

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

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

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