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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
---
title: Worker.postMessage()
slug: Web/API/Worker/postMessage
tags:
- Worker
- Worker.postMessage()
- postMessage()
translation_of: Web/API/Worker/postMessage
---
<p>{{APIRef("Web Workers API")}}</p>
<p>{{domxref("Worker")}} 接口的 <code><strong>postMessage()</strong></code>方法向worker的内部作用域发送一个消息。这接受单个参数,这是要发送给worker的数据。数据可以是由<a href="https://developer.mozilla.org/en-US/docs/Web/Guide/DOM/The_structured_clone_algorithm">结构化克隆</a>算法处理的任何值或JavaScript对象,其包括循环引用。</p>
<p>工作者可以使用 {{domxref("DedicatedWorkerGlobalScope.postMessage")}} 方法将信息发送回生成它的线程。</p>
<h2 id="语法">语法</h2>
<pre class="brush: js">myWorker.postMessage(aMessage, transferList);</pre>
<h3 id="参数">参数</h3>
<dl>
<dt><em>aMessage</em></dt>
<dd>The object to deliver to the worker; this will be in the data field in the event delivered to the {{domxref("DedicatedWorkerGlobalScope.onmessage")}} handler. This may be any value or JavaScript object handled by the <a href="/en-US/docs/Web/Guide/DOM/The_structured_clone_algorithm" title="http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#transferable">structured clone</a> algorithm, which includes cyclical references.</dd>
<dt><em>transferList</em> {{optional_inline}}</dt>
<dd>一个可选的{{domxref("Transferable")}}对象的<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">数组</a>,用于传递所有权。如果一个对象的所有权被转移,在发送它的上下文中将变为不可用(中止),并且只有在它被发送到的worker中可用。</dd>
<dd>可转移对象是如{{domxref("ArrayBuffer")}},{{domxref("MessagePort")}}或{{domxref("ImageBitmap")}}的实例对象。transferList数组中不可传入null。</dd>
</dl>
<h3 id="Returns">Returns</h3>
<p>Void.</p>
<h2 id="Example">Example</h2>
<p>以下代码显示了如何使用 {{domxref("Worker.Worker", "Worker()")}} 构造函数创建一个Worker对象。当两个表单输入(<code>first</code>和<code>second)</code>中的其中一个的输入值改变时, {{event("change")}} 事件将调用<code>postMessage()</code>把两个input的值发送给当前worker。</p>
<pre class="brush: js">var myWorker = new Worker('worker.js');
first.onchange = function() {
myWorker.postMessage([first.value,second.value]);
console.log('Message posted to worker');
}
second.onchange = function() {
myWorker.postMessage([first.value,second.value]);
console.log('Message posted to worker');
}
</pre>
<p>有关完整的示例,请参阅我们的<a class="external external-icon" href="https://github.com/mdn/simple-web-worker">Basic dedicated worker example</a> (<a class="external external-icon" href="http://mdn.github.io/simple-web-worker/">run dedicated worker</a>).</p>
<div class="note">
<p><strong>Note</strong>: <code>postMessage()</code> 一次只能发送一个对象。如上所示,如果你想传递多个值,可以使用数组。</p>
</div>
<h3 id="Transfer_Example">Transfer Example</h3>
<p>This example shows a Firefox add-on that transfers an <code>ArrayBuffer</code> from the main thread to the <code>ChromeWorker</code>, and then the <code>ChromeWorker</code> transfers it back to the main thread.</p>
<h4 id="Main_thread_code">Main thread code:</h4>
<pre class="brush: js">var myWorker = new ChromeWorker(self.path + 'myWorker.js');
function handleMessageFromWorker(msg) {
console.log('incoming message from worker, msg:', msg);
switch (msg.data.aTopic) {
case 'do_sendMainArrBuff':
sendMainArrBuff(msg.data.aBuf)
break;
default:
throw 'no aTopic on incoming message to ChromeWorker';
}
}
myWorker.addEventListener('message', handleMessageFromWorker);
// Ok lets create the buffer and send it
var arrBuf = new ArrayBuffer(8);
console.info('arrBuf.byteLength pre transfer:', arrBuf.byteLength);
myWorker.postMessage(
{
aTopic: 'do_sendWorkerArrBuff',
aBuf: arrBuf // The array buffer that we passed to the transferrable section 3 lines below
},
[
arrBuf // The array buffer we created 9 lines above
]
);
console.info('arrBuf.byteLength post transfer:', arrBuf.byteLength);
</pre>
<h4 id="Worker_code">Worker code</h4>
<pre class="brush: js">self.onmessage = function (msg) {
switch (msg.data.aTopic) {
case 'do_sendWorkerArrBuff':
sendWorkerArrBuff(msg.data.aBuf)
break;
default:
throw 'no aTopic on incoming message to ChromeWorker';
}
}
function sendWorkerArrBuff(aBuf) {
console.info('from worker, PRE send back aBuf.byteLength:', aBuf.byteLength);
self.postMessage({aTopic:'do_sendMainArrBuff', aBuf:aBuf}, [aBuf]);
console.info('from worker, POST send back aBuf.byteLength:', aBuf.byteLength);
}
</pre>
<h4 id="Output_logged">Output logged</h4>
<pre>arrBuf.byteLength pre transfer: 8 bootstrap.js:40
arrBuf.byteLength post transfer: 0 bootstrap.js:42
from worker, PRE send back aBuf.byteLength: 8 myWorker.js:5:2
incoming message from worker, msg: message { ... } bootstrap.js:20
got back buf in main thread, aBuf.byteLength: 8 bootstrap.js:12
from worker, POST send back aBuf.byteLength: 0 myWorker.js:7:2</pre>
<p><code>byteLength</code> goes to 0 as it is transferred. To see a full working example of this Firefox demo add-on see here: <a href="https://github.com/Noitidart/ChromeWorker/tree/aca57d9cadc4e68af16201bdecbfb6f9a6f9ca6b">GitHub :: ChromeWorker - demo-transfer-arraybuffer</a></p>
<h2 id="Specifications">Specifications</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', "#dom-worker-postmessage", "Worker.postMessage()")}}</td>
<td>{{Spec2('HTML WHATWG')}}</td>
<td>No change from {{SpecName("Web Workers")}}.</td>
</tr>
<tr>
<td>{{SpecName('Web Workers', "#dom-worker-postmessage", "Worker.postMessage()")}}</td>
<td>{{Spec2('Web Workers')}}</td>
<td>Initial definition.</td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibility">Browser compatibility</h2>
<div>{{CompatibilityTable}}</div>
<div id="compat-desktop">
<table class="compat-table">
<tbody>
<tr>
<th>Feature</th>
<th>Chrome</th>
<th>Firefox (Gecko)</th>
<th>Internet Explorer</th>
<th>Opera</th>
<th>Safari (WebKit)</th>
</tr>
<tr>
<td>Basic support</td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatVersionUnknown}}</td>
<td>10.0 [1]</td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatVersionUnknown}}</td>
</tr>
</tbody>
</table>
</div>
<div id="compat-mobile">
<table class="compat-table">
<tbody>
<tr>
<th>Feature</th>
<th>Android</th>
<th>Firefox Mobile (Gecko)</th>
<th>Firefox OS (Gecko)</th>
<th>IE Phone</th>
<th>Opera Mobile</th>
<th>Safari Mobile</th>
</tr>
<tr>
<td>Basic support</td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatVersionUnknown}}</td>
<td>10.0 [1]</td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatVersionUnknown}}</td>
</tr>
</tbody>
</table>
</div>
<p>[1] Internet Explorer does not support {{domxref("Transferable")}} objects.</p>
<h2 id="See_also">See also</h2>
<ul>
<li>The {{domxref("Worker")}} interface it belongs to.</li>
</ul>
|