We're looking for a user researcher to understand the needs of developers and designers. Is this you or someone you know? Check out the post: https://mzl.la/2IGzdXS

Перевод не завершен. Пожалуйста, помогите перевести эту статью с английского.

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

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

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

Свойства

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

AbstractWorker.onerror
EventListener который вызывается всегда, когда ErrorEvent типа error всплывает через воркер.
SharedWorker.port Только для чтения
Возвращает объект MessagePort, используемый для коммуникации и контроля разделяемого воркера.

Constructors

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

Методы

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

Пример

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

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

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

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

myWorker.port.start();

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

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 для обработки сообщений, присылаемых от обоих потоков.

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. Иначе вызывается неявно после установки хэндлера onmessage.
}

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

 

test.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
...
<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
...
<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 Status Comment
HTML Living Standard
Определение 'SharedWorker' в этой спецификации.
Живой стандарт No change from Unknown.

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

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Поддержка 4 29.0 (29.0) Нет 10.60 5
Нет 6.1
Feature Android Chrome for Android Firefox Mobile (Gecko) Firefox OS (Gecko) IE Mobile Opera Mobile Safari Mobile
Поддержка Нет Нет 33.0 (33.0) 2.1 Нет 11.5 5.1
Нет 7.1

See also

Метки документа и участники

Внесли вклад в эту страницу: Mihail-Afanasiev, IgorBaranov
Обновлялась последний раз: Mihail-Afanasiev,