Chapter 10 Web工作线程
0 Web工作线程原则
工作线程是重量级资源。
虽然从代码来看创建工作线程箱单简单,但这需要额外的内存和一个操作系统线程,在启动时间和资源方面开销可能很昂贵。
应创建有限的工作线程,并适当地设计计算来充分利用这些工作线程。
1 JavaScript单线程工作
JavaScript是单线程的,若任务时间太长,浏览器可能提示"Slow Script"
2 Web工作线程
-
Web工作线程是一个单独的线程处理任务,主JavaScript代码启动Web工作线程后,可以继续运行并对用户界面保持响应
-
Web工作线程由一单独的JavaScript文件定义
-
Web工作线程不能访问页面代码中的函数或DOM
-
检测浏览器对Web工作线程的支持性
if(window["Worker"]) { //浏览器支持Web工作线程 }
3 主页面与Web工作线程通信
- 主页面代码与Web工作线程通过message通信
- 主页面通过
worker.postMessage(message)
向工作线程发送消息;工作线程开始工作,完成后通过postMessage(message)
返回处理结果 - message可以是字符串、对象、数组等,但不能是函数,以保证工作线程不能修改DOM
- message为对象时,发送的是对象副本,而不是原对象的引用(与JavaScript函数调用传入对象不同)
- 主页面将工作线程的onmessage属性设置为处理函数,以接受工作线程返回的消息;工作线程也将其onmessage属性设置为处理函数,以接受主页面代码发送的消息
- 工作线程结果封装在事件对象event中,并置于event.data属性中
- 使用多个Web工作线程时,可以使用event.target属性查找哪个工作线程发出了消息
4 Web工作线程程序实现——主页面端
var worker = new Worker("worker.js");
worker.postMessage("ping");
worker.onmessage = function(event) {
console.log(event.target + " returns " + event.data);
};
5 Web工作线程程序实现——工作线程端
onmessage = function(event) {
//对于该JS文件,全局对象为worker,因此worker.onmessage可简写为onmessage
if(event.data == "ping") {
postMessage("pong");
}
};
6 Web工作线程权限
- message在主页面代码和工作线程之间会复制,而非共享,因此传递对象时工作线程将得到对象副本
- 主页面不能向工作线程传递函数
- 工作线程不能访问DOM,以及主页面的函数和变量
- 工作线程可访问localStorage和主页面创建的XMLHttpRequest
7 importScripts函数
-
要在工作线程文件中包含和使用JavaScript库,可使用
importScripts("---.js");
-
调用importScripts来利用JSONP,从而在工作线程文件中实现传入URL查询的回调
function makeServerRequest() { importScripts("http://SomeServer.com?callback=handleRequest"); } function handleRequest(response) { postMessage(response); } makeServerRequest();
8 工作线程的应用
- 使用多个工作线程完成能分解为多个任务的大规模计算
- 每个工作线程在自己的线程中运行,若计算机有一个多核处理器,工作线程将会并行运行,从而提高计算的速度
9 中止工作线程
-
主页面停止工作线程并将其清除
worker.terminate();
-
在工作线程内停止工作线程
close(); //worker为全局对象,worker.close()可简写为close()
10 处理工作线程错误
worker.onerror = function(error) {
//错误处理程序
console.log(error.filename + error.message);
}
11 子工作线程
如果工作线程完成任务时需要帮助,可以创建自己的工作线程