一、介绍
当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成。
web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。您可以继续做任何愿意做的事情:点击、选取内容等等,而此时 web worker 在后台运行。
二、限制
- Web Worker无法访问DOM节点;
- Web Worker无法访问全局变量或是全局函数;
- Web Worker无法调用alert()或者confirm之类的函数;
- Web Worker无法访问window、document之类的浏览器全局变量;
三、worker与sharedWorker
Web workers可分为两种类型:专用线程、共享线程。
专用线程随当前页面的关闭而结束;这意味着专用线程只能被创建它的页面访问。
与之相对应的共享线程r可以被多个页面访问。
专用线程
let worker = new Worker("worker.js");
共享线程
let worker = new SharedWorker("sharedworker.js");
四、worker的通信
专用线程
使用 onmessage() , postmessage()通信
/** 主线程 **/
let worker = new Worker ('worker.js')
worker.onmessage = (e) => {
console.log(e.data) // I post a message to main thread
}
worker.postMessage('main thread got a message')
/** 子线程 worker.js **/
onmessage = (e) => {
console.log(e.data) // main thread got a message
}
postMessage('I post a message to main thread')
共享线程
SharedWorker需要用到port属性,接收需要先connect
/** 主线程 **/
worker.port.onmessage = function(e){}
worker.port.postMessage('data');
/** 子线程 **/
addEventListener('connect', function(event){
var port = event.ports[]
//接收
port.onmessage = function(event){
console.log(event.data);
};
//发送
port.postMessage("data");
port.start();
});
五、worker.js里引入外部js
// 引入一个脚本
importScripts('xxx.js');
// 引入多个脚本
importScripts('aaa.js', 'bbb.js', 'ccc.js');
六、结束线程
// 在主线程中终止
worker.terminate()
// 在子线程中终止自身
self.close()
七、错误监听
worker.addEventListener("error", function(evt){
alert("Line #" + evt.lineno + " - " + evt.message + " in " + evt.filename);
}, false);
worker.postMessage();
});
如上可见, Worker对象可以绑定error事件;而且evt对象中包含错误所在的代码文件(evt.filename)、错误所在的代码行数(evt.lineno)、以及错误信息(evt.message)。
八、使用inline的worker.js
let blob = new Blob(['/*worker.js的代码*/']);
let blobURL = window.URL.createObjectURL(blob);
worker = new Worker(blobURL);
附:项目中用到的简单原生ajax
addEventListener("message", function(evt){
var xhr = new XMLHttpRequest();
xhr.open("GET", "lengthytaskhandler.ashx");
xhr.onload = function(){
postMessage(xhr.responseText);
};
xhr.send();
},false);