1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
---
title: SharedWorker
slug: Web/API/SharedWorker
translation_of: Web/API/SharedWorker
---
<div>{{APIRef("Web Workers API")}}</div>
<p><code><font face="Open Sans, arial, x-locale-body, sans-serif"><span style="background-color: #ffffff;">Интерфейс </span></font><strong>SharedWorker </strong>(разделяемый воркер)</code> является особым видом воркеров к которому можно получить доступ из нескольких контекстов браузера, например, из нескольких окон, iframe, или других воркеров. Этот интерфейс реализован иначе, чем dedicated воркеры и имеют иной глобальный контекст, {{domxref("SharedWorkerGlobalScope")}}.</p>
<div class="note">
<p><strong>Замечание:</strong> Если SharedWorker может быть доступен из нескольких контекстов браузера, все они должны разделять одинаковое расположение (идентичные протокол, хост и порт).</p>
</div>
<div class="note">
<p><strong>Замечание</strong>: В Firefox, разделяемые воркеры не могут взаимодействовать между private (например, просматриваемыми в приватном режиме) и non-private документами (см. {{bug(1177621)}}.)</p>
</div>
<h2 id="Свойства">Свойства</h2>
<p><em>Наследует свойства родителя, {{domxref("EventTarget")}}, и реализует свойства {{domxref("AbstractWorker")}}.</em></p>
<dl>
<dt>{{domxref("AbstractWorker.onerror")}}</dt>
<dd>{{domxref("EventListener")}} который вызывается всегда, когда {{domxref("ErrorEvent")}} типа <code>error</code> всплывает через воркер.</dd>
<dt>{{domxref("SharedWorker.port")}} {{readonlyInline}}</dt>
<dd>Возвращает объект {{domxref("MessagePort")}}, используемый для коммуникации и контроля разделяемого воркера.</dd>
</dl>
<h2 id="Constructors">Constructors</h2>
<dl>
<dt>{{domxref("SharedWorker.SharedWorker", "SharedWorker()")}}</dt>
<dd>Создаёт разделяемый веб воркер, который выполняет скрипт по указанному URL.</dd>
</dl>
<h2 id="Методы">Методы</h2>
<p><em>Наследует методы родительского класса, {{domxref("EventTarget")}}, и реализует свойства {{domxref("AbstractWorker")}}.</em></p>
<h2 id="Пример">Пример</h2>
<p>В нашем <a class="external external-icon" href="https://github.com/mdn/simple-shared-worker">Базовом примере разделяемого воркера</a> (<a class="external external-icon" href="http://mdn.github.io/simple-shared-worker/">запустить</a>), имеются две HTML страницы, каждая из которых использует JavaScript для простых вычислений. Разные скрипты используют один и тот же воркер, чтобы выполнить умножение двух чисел - они оба имеют доступ к нему, даже если их страницы запущены в разных окнах.</p>
<p>Следующий пример кода демонстрирует создание объекта <code>SharedWorker</code> с использованием конструктора {{domxref("SharedWorker.SharedWorker", "SharedWorker()")}}. Оба скрипта содержат:</p>
<pre class="brush: js">var myWorker = new SharedWorker("worker.js");
</pre>
<p>далее скрипты получают доступ к воркеру через объект {{domxref("MessagePort")}}, находящийся в свойстве {{domxref("SharedWorker.port")}}. Если устанавливается обработчик события onmessage, port самостоятельно начинает работу, вызывая собственный метод <code>start(), </code>если же принимать события с помощью обработчика события "message" через addEventListener, необходимо вызвать метод <code>start()</code> самостоятельно:</p>
<pre class="brush: js">myWorker.port.start();</pre>
<p>После того, как порт запущен, оба скрипта отправляют сообщения воркеру и принимают их от него, используя <code>port.postMessage()</code> и <code>port.onmessage</code>, соответственно:</p>
<pre class="brush: 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');
}</pre>
<p>Внутри воркера используется хэндлер {{domxref("SharedWorkerGlobalScope.onconnect")}} для соединения к тому же порту, как обсуждалось ранее. Порты, связанные с данным воркером доступны в свойстве ports события {{event("connect")}}. Далее вызывается метод {{domxref("MessagePort")}} <code>start()</code> для запуска порта, и устанавливается хэндлер <code>onmessage</code> для обработки сообщений, присылаемых от обоих потоков.</p>
<pre class="brush: 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, данный метод вызывается автоматически, неявно
}</pre>
<h3 id="Пример_с_несколькими_страницами">Пример с несколькими страницами</h3>
<h4 id="sect1"> </h4>
<pre><strong>test.js
</strong>
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);
<strong>На странице 1 получаем сообщение '</strong>worker init<strong>' в консоли.
index1.html
...</strong>
<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>
<strong>...
На странице 2 в консоль выводится 'worker already inited', так как страница 1 уже запустила наш воркер;
</strong>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>
...</pre>
<p> </p>
<p> </p>
<p> </p>
<h2 id="sect2"> </h2>
<h2 id="Спецификации">Спецификации</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
<tr>
<td>{{SpecName('HTML WHATWG', "#sharedworker", "SharedWorker")}}</td>
<td>{{Spec2('HTML WHATWG')}}</td>
<td>No change from {{SpecName("Web Workers")}}.</td>
</tr>
</tbody>
</table>
<h2 id="Совместимость_браузеров">Совместимость браузеров</h2>
<p>{{Compat("api.SharedWorker")}}</p>
<h2 id="See_also">See also</h2>
<ul>
<li>{{domxref("Worker")}}</li>
<li><a class="internal" href="/en-US/docs/Web/Guide/Performance/Using_web_workers">Использование веб воркеров</a></li>
</ul>
|