Web Workers
我们都知道,JavaScript是单线程运行。我们在界面上看到的所谓同时的操作,其实都是任务之间的不断切换造成的假象,本质上还是单线程在运行。而Web Workers试图想打破这种单线程运行的局面,因为每创建一个新的Worker,就会产生一个真正操作系统级别的线程出来,我们可以把一定的任务量交给Worker来完成,这样是不是打破了JavaScript单线程运行的本质呢?其实并没有。至少在worker内,是不能操作DOM节点的,也不能使用window对象默认的方法和属性。
创建
// 指定一个脚本worker.js来执行worker线程
let myWorker = new Worker('worker.js')
通信
worker与脚本之间的通信用的是postMessage()方法和onmessage事件来完成。
firstInput.onchange = function() {
myWorker.postMessage([first.value,second.value])
console.log('first input value posted to worker')
}
secondInput.onchange = function() {
myWorker.postMessage([first.value,second.value])
console.log('second input value posted to worker')
}
我们在脚本中监听了两个input输入框的值,任何一个有变化时,都会给myWorker发送消息,然后在worker.js中接收消息。
onmessage = function(e) {
console.log('Message received from main script')
var workerResult = 'Result: ' + (e.data[0] * e.data[1])
console.log('Posting message back to main script')
postMessage(workerResult) // 给脚本发送消息
}
相反,也可以在worker中给脚本发送消息,发送和接收的方式相同。消息的内容并非共享,而是被复制或转移了。
终止
在主线程中,如果需要终止一个worker,可以调用它的terminate()方法:
myWorker.terminate()
如果终止任务需要worker自身来完成,可以在worker中调用close()方法:
close()
错误处理
当worker发生错误时,我们通过onerror事件来监听,事件会接收到3个参数:
- errorMsg 错误消息
- filename 发生错误的文件名
- lineno 发生错误的脚本行号
myWorker.onerror = function (errorMsg, filename, lineno) {
// TODO
}