Интерфейс SharedWorker (разделяемый воркер)
является особым видом воркеров к которому можно получить доступ из нескольких контекстов браузера, например, из нескольких окон, iframe, или других воркеров. Этот интерфейс реализован иначе, чем dedicated воркеры и имеют иной глобальный контекст, SharedWorkerGlobalScope
.
Замечание: Если SharedWorker может быть доступен из нескольких контекстов браузера, все они должны разделять одинаковое расположение (идентичные протокол, хост и порт).
Замечание: В 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. |
Совместимость браузеров
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 |