全栈之旅:javaScript 进阶 - Web Workers

101 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

Web Workers

介绍

Web Worker 为 Web 内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面。此外,他们可以使用XMLHttpRequest执行 I/O (尽管responseXMLchannel属性总是为空)。一旦创建,一个 worker 可以将消息发送到创建它的 JavaScript 代码,通过将消息发布到该代码指定的事件处理程序(反之亦然)。

专用workers和共享workers

1.专用workers

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

worker.js为你创建的js文件。

通信:

你可以通过postMessage() 方法和onmessage事件处理函数触发 workers 的方法。当你想要向一个 worker 发送消息时,你只需要这样做:

//main.js
first.onchange = function() {
  myWorker.postMessage([ value1, value2]);
  console.log('消息发送到worker');
}
//worker.js 
onmessage = function(e) {
  console.log('接受到了来自main.js的信息');
  var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
  console.log('信息处理完毕准备返回');
  postMessage(workerResult);
} 
//main.js
 
myWorker.onmessage = function(e) {
  result.textContent = e.data;
  console.log('接受到了worker处理完返回的信息');
}

终止worker

当你想要停止时,无论worker处于什么状态,都会被杀死。

//主线程中
myWorker.terminate();

或者

//worker线程中
close();

捕捉错误

当 worker 出现运行中错误时,它的 onerror 事件处理函数会被调用。它会收到一个扩展了 ErrorEvent 接口的名为 error的事件。 错误事件有以下三个用户关心的字段:

  • message 可读性良好的错误消息。
  • filename发生错误的脚本文件名。
  • lineno 发生错误时所在脚本文件的行号。

生成subworker

如果需要的话 worker 能够生成更多的 worker。这就是所谓的 subworker,它们必须托管在同源的父页面内。而且,subworker 解析 URI 时会相对于父 worker 的地址而不是自身页面的地址。这使得 worker 更容易记录它们之间的依赖关系。 你可以使用importScripts来引入多个脚本。

importScripts('worker1.js','worker2.js')

2.共享workers

当多个页面想要使用同一个worker时,需要使用SharedWorker

var myWorker = new SharedWorker('worker.js');

开启端口

//主线程
myWorker.port.start();

port.start();

假设port是一个端口

通信

和专用worker类似,只是需要前面加上端口port,

//main.js
first.onchange = function() {
  myWorker.port.postMessage([ value1, value2]);
  console.log('消息发送到worker');
}
//worker.js  
onconnect = function(e) {
  var port = e.ports[0];
  port.onmessage = function(e) {
    var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
    port.postMessage(workerResult);
  }
} 
//main.js 
myWorker.port.onmessage = function(e) {
  result.textContent = e.data;
  console.log('接受到了worker处理完返回的信息');
}

首先,当一个端口连接被创建时(例如:在父级线程中,设置 onmessage 事件处理函数,或者显式调用 start() 方法时),使用 onconnect 事件处理函数来执行代码。 使用事件的 ports 属性来获取端口并存储在变量中。