1
2
3
// index.js
var worker = new Worker ('worker.js')
worker.postMessage() // start the worker

postMessage 方法可以接受字符串或 JSON 对象

1
2
3
4
5
6
// index.js
worker.addEventListener('message', (e) => {
console.log('worker said: ', e.data)
}, false)

worker.postMessage('hello world')
1
2
3
4
// worker.js
self.addEventListener('message', (e) => {
self.postMessage(e.data)
}, false)

index.js 中调用 postMessage() 时, worker.js 通过 message 时间处理消息, index.js 的有效信息在 e.data 上.

index.js 和 worker.js 传递的消息是幅值而不是共享(序列化+反序列化)

Example

1
2
3
4
<button onclick="sayHi()">SayHi</button>
<button onclick="unknownCmd()">unknownCmd</button>
<button onclick="stop()"></button>
<output id="result"></output>
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
// index.js
function sayHi () {
worker.postMessage({
cmd: 'start',
msg: 'Hi',
})
}

function stop () {
worker.postMessage({
cmd: 'stop',
msg: 'Bye',
})
}

function unknownCmd () {
worker.postMessage({
cmd: 'foobar',
msg: '???',
})
}

var worker = new Worker('worker.js')

worker.addEventListener('message', function (e) {
document.getElementById('result').textContent = e.data
}, false)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// worker.js
self.addEventListener('message', function (e) {
var data = e.data
switch (data.cmd) {
case 'start': {
self.postMessage('WORKER STARTED: ' + data.msg)
break
}
case 'stop': {
self.postMessage('WORKER STOPPED: ' + data.msg + '. (buttons will no longer work)')
self.close()
break
}
default: {
self.postMessage('Unknown command: ' + data.msg)
}
}
}, false)

停止 worker 的方法两种

1
2
// index.js
worker.terminate()
1
2
// worker.js
self.close()

Worker 环境

Worker 作用域

在 worker.js 中, self 和 this 都是指 worker 的全局作用域

适用于 worker 的功能

由于web worker 的多线程行为, 所以他们只能使用 js 功能的子集

  • navigator 对象

  • location 对象

  • XMLHttpResponse

  • setTimeout() / clearTimeout() / setInterval() / clearInterval()

  • 应用缓存

  • 使用 importScripts() 方法导入外部脚本

  • 生成其他 worker

worker 无法使用:

  • DOM

  • window 对象

  • document 对象

  • parent 对象

加载外部脚本

worker 可以通过 importScripts() 函数将外部脚本文件或库加载到 worker 中, 该方法采用零个或多个字符串表示要导入的资源名.

1
2
3
4
5
// worker.js
importScripts('script1.js')
importScripts('script2.js')

importScripts('script3.js', 'script4.js')

添加子 worker

  • subWorker 必须托管在与福网页相同的来源中

  • subWorker 中的 URI 应相对于 worker 的位置来解析

处理错误

执行的 worker 发生错误时, 会触发 ErrorEvent, 包含三个属性: filename, lineno, message