--- title: SharedWorker slug: Web/API/SharedWorker translation_of: Web/API/SharedWorker ---
{{APIRef("Web Workers API")}}

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

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

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

Свойства

Наследует свойства родителя, {{domxref("EventTarget")}}, и реализует свойства {{domxref("AbstractWorker")}}.

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

Constructors

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

Методы

Наследует методы родительского класса, {{domxref("EventTarget")}}, и реализует свойства {{domxref("AbstractWorker")}}.

Пример

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

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

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

далее скрипты получают доступ к воркеру через объект {{domxref("MessagePort")}}, находящийся в свойстве {{domxref("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');
  }

Внутри воркера используется хэндлер {{domxref("SharedWorkerGlobalScope.onconnect")}} для соединения к тому же порту, как обсуждалось ранее. Порты, связанные с данным воркером доступны в свойстве ports события {{event("connect")}}. Далее вызывается метод {{domxref("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
{{SpecName('HTML WHATWG', "#sharedworker", "SharedWorker")}} {{Spec2('HTML WHATWG')}} No change from {{SpecName("Web Workers")}}.

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

{{CompatibilityTable}}

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Поддержка {{CompatChrome(4)}} {{CompatGeckoDesktop(29.0)}} {{CompatNo}} {{CompatOpera(10.60)}} 5
{{CompatNo}} 6.1
Feature Android Chrome for Android Firefox Mobile (Gecko) Firefox OS (Gecko) IE Mobile Opera Mobile Safari Mobile
Поддержка {{CompatNo}} {{CompatNo}} {{CompatGeckoMobile("33.0")}} 2.1 {{CompatNo}} 11.5 5.1
{{CompatNo}} 7.1

See also