Worker: примеры (JAVASCRIPT)

Функция Worker в JavaScript для параллельных вычислений
Раздел: Web Workers, Конструкторы
Worker(scriptURL (string), options (object)): Worker

Обзор функции Worker

Конструктор Worker в JavaScript используется для создания веб-воркеров - скриптов, выполняющихся в фоновом потоке, отдельно от основного потока веб-страницы. Эта функция применяется для выполнения ресурсоемких задач без блокировки пользовательского интерфейса.

Worker создается путем передачи URL-адреса JavaScript-файла:

new Worker('worker.js');
Конструктор принимает два необязательных параметра:

  • scriptURL - строка, представляющая URL скрипта воркера
  • options - объект со свойствами:
    • type - определяет тип воркера: 'classic' (по умолчанию) или 'module'
    • credentials - указывает учетные данные для сетевых запросов: 'omit', 'same-origin' или 'include'
    • name - строка идентификатора для воркера

Возвращает объект Worker, предоставляющий методы для взаимодействия с фоновым потоком.

Базовые примеры использования

Простой воркер для вычислений:

// Основной поток
const worker = new Worker('calculate.js');
worker.postMessage({numbers: [1, 2, 3, 4, 5]});
worker.onmessage = (event) => {
  console.log('Результат:', event.data);
};

// calculate.js
self.onmessage = (event) => {
  const sum = event.data.numbers.reduce((a, b) => a + b, 0);
  self.postMessage(sum);
};
Результат: 15

Воркер с параметрами:

const worker = new Worker('module-worker.js', {
  type: 'module',
  name: 'mathWorker',
  credentials: 'same-origin'
});

Альтернативы в JavaScript

  • SharedWorker - позволяет нескольким окнам или вкладкам использовать один воркер. Применяется для синхронизации данных между вкладками.
  • Service Worker - работает как прокси между браузером и сетью, используется для офлайн-работы и кэширования.
  • setTimeout/setInterval - для легких фоновых задач, но выполняются в основном потоке.
  • requestIdleCallback - планирует задачи на периоды простоя браузера.

Распространенные ошибки

Попытка прямого доступа к DOM:

// worker.js
self.onmessage = () => {
  document.getElementById('result').textContent = 'Ошибка!';
  // Ошибка: DOM недоступен в воркере
};

Некорректная обработка сообщений:

const worker = new Worker('worker.js');
worker.postMessage('данные');
// Ошибка: не установлен обработчик onmessage
// Сообщения будут потеряны

Отсутствие завершения воркера:

// Утечка памяти
for(let i = 0; i < 1000; i++) {
  const worker = new Worker('task.js');
  // worker.terminate() не вызывается
}

Последние изменения

В современных браузерах добавлена поддержка ES-модулей в воркерах через параметр {type: 'module'}:

const worker = new Worker('./module.js', {
  type: 'module'
});

Добавлена поддержка Worker Node.js в версии 10.5.0. Введены динамические импорты в воркерах. Улучшена обработка ошибок через событие onerror.

Расширенные примеры

Воркер с обработкой изображений:

Пример javascript
// Основной скрипт
const imageWorker = new Worker('image-processor.js');
canvas.toBlob(blob => {
  imageWorker.postMessage({image: blob, filter: 'grayscale'});
});

// image-processor.js
self.onmessage = async (event) => {
  const bitmap = await createImageBitmap(event.data.image);
  // Обработка изображения...
  self.postMessage(processedBitmap);
};

Пул воркеров для параллельной обработки:

Пример javascript
class WorkerPool {
  constructor(script, size) {
    this.workers = [];
    for(let i = 0; i < size; i++) {
      this.workers.push({
        worker: new Worker(script),
        busy: false
      });
    }
  }
  
  execute(task) {
    const available = this.workers.find(w => !w.busy);
    if(available) {
      available.busy = true;
      return new Promise(resolve => {
        available.worker.onmessage = (event) => {
          available.busy = false;
          resolve(event.data);
        };
        available.worker.postMessage(task);
      });
    }
  }
}

Воркер с разделяемой памятью:

Пример javascript
// Создание SharedArrayBuffer
const sharedBuffer = new SharedArrayBuffer(1024);
const worker = new Worker('shared-worker.js');
worker.postMessage({buffer: sharedBuffer});

// shared-worker.js
self.onmessage = (event) => {
  const sharedArray = new Int32Array(event.data.buffer);
  Atomics.add(sharedArray, 0, 1); // Атомарная операция
};

Аналоги в других языках

Python (модуль multiprocessing):

from multiprocessing import Process
def calculate(numbers):
    return sum(numbers)

if __name__ == '__main__':
    p = Process(target=calculate, args=([1,2,3,4,5],))
    p.start()
    p.join()

PHP (расширение pcntl):

$pid = pcntl_fork();
if ($pid == 0) {
    // Дочерний процесс
    exit();
}

Java (потоки):

Thread worker = new Thread(() -> {
    // Фоновая задача
});
worker.start();

JS Worker function comments

En
Worker Creates a web worker for parallel execution