Web Workers

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

Web Workers API

  • 一个worker是使用一个构造函数创建的一个对象(e.g. Worker()) 运行一个命名的JavaScript文件
  • workers 运行在另一个全局上下文中,不同于当前的window
    • 使用 window快捷方式获取当前全局的范围 (而不是self) 在一个 Worker 内将返回错误。
  • DedicatedWorkerGlobalScope 对象代表了专用worker的上下文
    • 专用workers是指标准worker仅在单一脚本中被使用,一个专用worker仅仅能被首次生成它的脚本使用
  • 共享worker的上下文是SharedWorkerGlobalScope对象,共享worker可以同时被多个脚本使用。
  • 在worker内,不能直接操作DOM节点,也不能使用window对象的默认方法和属性。
  • 可以使用包括WebSockets,IndexedDB等数据存储机制。参考https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API/Functions_and_classes_available_to_workers
  • workers和主线程间的数据传递通过这样的消息机制进行——双方都使用postMessage()方法发送各自的消息,使用onmessage事件处理函数来响应消息(消息被包含在Message事件的data属性中)。
    • 这个过程中数据并不是被共享而是被复制。
  • 只要运行在同源的父页面中,workers可以依次生成新的workers

专用worker

worker特性检测

  • 为了更好的错误处理控制以及向下兼容,将你的worker运行代码包裹在以下代码中是一个很好的想法
if (window.Worker) { ... }

生成一个专用worker

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

专用worker中消息的接收和发送

  • 在worker内部,worker是有效的全局作用域。
// 主线程中
// 发送
first.onchange = function() { // first是一个input元素
  myWorker.postMessage([first.value]);
  console.log('Message posted to worker');
}
// 接收
myWorker.onmessage = function(e) {
  result.textContent = e.data; // result是个p元素
  console.log('Message received from worker');
}

// worker.js 中
// 接收和发送
onmessage = function(e) {
  console.log('Message received from main script');
  var workerResult = 'Result: ' + (e.data[0] * 10);
  console.log('Posting message back to main script');
  postMessage(workerResult);
}

终止worker

  • worker 线程会被立即杀死,不会有任何机会让它完成自己的操作或清理工作。
// 主线程中
myWorker.terminate();
  • 而在worker线程中,workers 也可以调用自己的 close 方法进行关闭
close();

处理错误

  • 当 worker 出现运行中错误时,它的 one rror 事件处理函数会被调用
  • 会收到一个扩展了 ErrorEvent 接口的名为 error的事件
  • 该事件不会冒泡但可以被取消
  • 可以调用错误事件的 preventDefault()方法,防止触发默认动作
上一篇:第十八课--H5Web Workers


下一篇:concurrent.futures模块简单介绍(线程池,进程池)