This page was translated from English by the community. Learn more and join the MDN Web Docs community.

View in English Always switch to English

SharedWorker

Limited availability

This feature is not Baseline because it does not work in some of the most widely-used browsers.

Интерфейс SharedWorker (разделяемый воркер) является особым видом воркеров к которому можно получить доступ из нескольких контекстов браузера, например, из нескольких окон, iframe, или других воркеров. Этот интерфейс реализован иначе, чем dedicated воркеры и имеют иной глобальный контекст, SharedWorkerGlobalScope.

Примечание: Если SharedWorker может быть доступен из нескольких контекстов браузера, все они должны разделять одинаковое расположение (идентичные протокол, хост и порт).

Примечание: В Firefox, разделяемые воркеры не могут взаимодействовать между private (например, просматриваемыми в приватном режиме) и non-private документами (см. Firefox bug 1177621.)

Свойства

Наследует свойства родителя, EventTarget, и реализует свойства AbstractWorker.

AbstractWorker.onerror

EventListener который вызывается всегда, когда ErrorEvent типа error всплывает через воркер.

SharedWorker.port Только для чтения

Возвращает объект MessagePort, используемый для коммуникации и контроля разделяемого воркера.

Constructors

SharedWorker()

Создаёт разделяемый веб воркер, который выполняет скрипт по указанному URL.

Методы

Наследует методы родительского класса, EventTarget, и реализует свойства AbstractWorker.

Пример

В нашем Базовом примере разделяемого воркера (запустить), имеются две HTML страницы, каждая из которых использует JavaScript для простых вычислений. Разные скрипты используют один и тот же воркер, чтобы выполнить умножение двух чисел - они оба имеют доступ к нему, даже если их страницы запущены в разных окнах.

Следующий пример кода демонстрирует создание объекта SharedWorker с использованием конструктора SharedWorker(). Оба скрипта содержат:

js
var myWorker = new SharedWorker("worker.js");

далее скрипты получают доступ к воркеру через объект MessagePort, находящийся в свойстве SharedWorker.port. Если устанавливается обработчик события onmessage, port самостоятельно начинает работу, вызывая собственный метод start(), если же принимать события с помощью обработчика события "message" через addEventListener, необходимо вызвать метод start() самостоятельно:

js
myWorker.port.start();

После того, как порт запущен, оба скрипта отправляют сообщения воркеру и принимают их от него, используя port.postMessage() и port.onmessage, соответственно:

js
first.onchange = function () {
  myWorker.port.postMessage([first.value, second.value]);
  console.log("Message posted to worker");
};

second.onchange = function () {
  myWorker.port.postMessage([first.value, second.value]);
  console.log("Message posted to worker");
};

myWorker.port.onmessage = function (e) {
  result1.textContent = e.data;
  console.log("Message received from worker");
};

Внутри воркера используется хэндлер SharedWorkerGlobalScope.onconnect для соединения к тому же порту, как обсуждалось ранее. Порты, связанные с данным воркером доступны в свойстве ports события connect. Далее вызывается метод MessagePort start() для запуска порта, и устанавливается хэндлер onmessage для обработки сообщений, присылаемых от обоих потоков.

js
onconnect = function (e) {
  var port = e.ports[0];
  // or port = e.source

  port.addEventListener("message", function (e) {
    var workerResult = "Result: " + e.data[0] * e.data[1];
    port.postMessage(workerResult);
  });

  port.start(); // необходимо при добавлении обработчиков с помощью addEventListener. При использовании сеттера port.onmessage, данный метод вызывается автоматически, неявно
};

Пример с несколькими страницами

test.js

js
let connected = false;
self.addEventListener(
  "connect",
  (e) => {
    e.source.addEventListener(
      "message",
      (ev) => {
        if (ev.data === "start") {
          if (connected === false) {
            e.source.postMessage("worker init");
            connected = true;
          } else {
            e.source.postMessage("worker already inited");
          }
        }
      },
      false,
    );
    e.source.start();
  },
  false,
);

На странице 1 получаем сообщение 'worker init' в консоли.

index1.html

html
<script>
  let worker = new SharedWorker("test.js");
  worker.port.addEventListener(
    "message",
    (e) => {
      console.log(e.data);
    },
    false,
  );
  worker.port.start();
  worker.port.postMessage("start");
</script>

На странице 2 в консоль выводится 'worker already inited', так как страница 1 уже запустила наш воркер;

index2.html

html
<script>
  let worker = new SharedWorker("test.js");
  worker.port.addEventListener(
    "message",
    (e) => {
      console.log(e.data);
    },
    false,
  );
  worker.port.start();
  worker.port.postMessage("start");
</script>

Спецификации

Specification
HTML
# shared-workers-and-the-sharedworker-interface

Совместимость с браузерами

Смотрите также