https://zhuanlan.zhihu.com/p/115243059
Web Worker
Worker 和 主线程互不干扰,通常用于替主线程分担计算密集型任务,防止主线程中JS执行时阻塞UI。
Worker本身也会耗费资源,因此一旦使用完毕,就应该分别使用terminate
和close
方法关闭。
- worker线程无法读取本地文件,因此其脚本文件也必须为网络资源,且必须与主线程脚本文件同源
- worker无法读取/操作dom对象,没有
alert()
和confirm()
方法,也无法获取document
、window
、parent
,但是可以获取navigator
和location
。
基本用法
主线程
- 主线程和web worker通过message事件传递信息(信息在event.data里)
- 通过
onerror
可以监听子线程中的报错,通过onmessageerror
可以监听通讯内容无法序列化成字符串
//webworker.html
var worker = new Worker('worker.js', { name : 'myWorker' });
worker.onerror = function (e) {
console.log('ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message);
};
worker.postMessage({ a: 18 });
worker.onmessage = function (event) {
console.log("event", event);
console.log('Received message ' + (event.data.a + event.data.b));
}
// worker.terminate();
- 通信是深拷贝关系,即是传值而不是传址,不会互相影响。当拷贝二进制内容(
File
、Blob
、ArrayBuffer
等)时可使用Transferable Objects
方式将数据转移而非拷贝,以节省内存
worker.postMessage(arrayBuffer, [arrayBuffer]);
// 例子
var ab = new ArrayBuffer(1);
worker.postMessage(ab, [ab]);
子线程
- 子线程中
this
指向全局对象self
(类似主线程中的windows) - 子线程可以通过
importScripts
加载其他JS - 通过
onmessageerror
可以监听通讯内容无法序列化成字符串
// worker.js
console.log("worker ready", this === self);
console.log(name);//myWorker
addEventListener(
"message",
function (e) {
postMessage(Object.assign(e.data, { b: 20 }));
},
false
);
importScripts("other.js");
// self.close();
service worker
基于web worker,充当服务器与浏览器之间的代理服务器(可以拦截请求,并作出开发者指定的动作),拥有离线缓存能力
网友评论