Web Worker
Web Worker 是HTML5标准的一部分,这一规范定义了一套 API,它允许一段JavaScript程序运行在主线程之外的另外一个线程中。
值得注意的是, Web Worker 规范中定义了两类工作线程,分别是专用线程Dedicated Worker和共享线程 Shared Worker,其中,Dedicated Worker只能为一个页面所使用,而Shared Worker则可以被多个页面所共享。
Javascript是运行在单线程环境中,也就是说无法同时运行多个脚本,如果放在web worker则可以启动一个独立的worker线程来专门负责这段代码的运行
Web Worker使用
只需调用Worker() 构造函数并传入一个要在 worker 线程内运行的脚本的URI,即可创建一个新的worker。
var myWorker = new Worker("my_task.js");
通过URL.createObjectURL()创建URL对象,可以实现创建内嵌的worker
注意:传入 Worker 构造函数的参数 URI 必须遵循同源策略。Worker线程的创建的是异步的,主线程代码不会阻塞在这里等待worker线程去加载、执行指定的脚本文件,而是会立即向下继续执行后面代码。
Web Worker线程之间的通行
Worker 与其主页面之间的通信是通过 onmessage 事件和 postMessage() 方法实现的。
由于Worker之间的通讯是进过拷贝完成,需要经过序列化和反序列化。所以与主页面不会共享一个实例。
即:传递引用类型的值,也不会相互影响
// JavaScript
var myTask = `
onmessage = function (e) {
var data = e.data;
data.push('hello');
console.log('worker:', data); // worker: [1, 2, 3, "hello"]
postMessage(data);
};
`;
var blob = new Blob([myTask]);
var myWorker = new Worker(window.URL.createObjectURL(blob));
myWorker.onmessage = function (e) {
var data = e.data;
console.log('page:', data); // page: [1, 2, 3, "hello"]
console.log('arr:', arr); // arr: [1, 2, 3]
};
var arr = [1,2,3];
myWorker.postMessage(arr);
worker 上下文
Worker执行的上下文,与主页面执行时的上下文并不相同,最顶层的对象并不是window,而是个一个叫做WorkerGlobalScope的东东,所以无法访问window、以及与window相关的DOM API,但是可以与setTimeout、setInterval等协作。
WorkerGlobalScope作用域下的常用属性、方法如下:
- self
我们可以使用 WorkerGlobalScope 的 self 属性来或者这个对象本身的引用 - location
location 属性返回当线程被创建出来的时候与之关联的 WorkerLocation 对象,它表示用于初始化这个工作线程的脚步资源的绝对 URL,即使页面被多次重定向后,这个 URL 资源位置也不会改变。 - close
关闭当前线程 - importScripts
我们可以通过importScripts()方法通过url在worker中加载库函数 - XMLHttpRequest
有了它,才能发出Ajax请求 - setTimeout/setInterval以及addEventListener/postMessage
关闭worker terminate()
// JavaScript
// 主页面调用
myWorker.terminate();
// Worker 线程调用
self.close();
处理错误
myWorker.onerror = function onError(e) {
console.log(['ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message].join(''));
}
总结
强大的计算能力
可以加载一个JS进行大量的复杂计算而不挂起主进程,并通过postMessage,onmessage进行通信,解决了大量计算对UI渲染的阻塞问题。
应用场景
1、数学运算
Web Worker最简单的应用就是用来做后台计算,对CPU密集型的场景再适合不过了。
2、图像处理
通过使用从canvas中获取的数据,可以把图像分割成几个不同的区域并且把它们推送给并行的不同Workers来做计算,对图像进行像素级的处理,再把处理完成的图像数据返回给主页面。
3、大数据的处理
目前mvvm框架越来越普及,基于数据驱动的开发模式也越愈发流行,未来大数据的处理也可能转向到前台,这时,将大数据的处理交给在Web Worker也是上上之策了吧。