尚未完成,请稍等
web worker
他与浏览器运行在不同的上下文中。浏览器整个全局上下文是一个Window对象,我们通过window来进行访问。
webworker是一个 DedicatedWorkerGlobalScope 对象,我们通过self来进行访问。

它上面有我们的绝大多数的Window对象的属性和方法。 他没有document对象,也不能够对DOM进行访问,但是可以以可读方式访问到location和navigator对象(用户的一些信息,例如Agent,浏览器版本,用户设备信息)。并且日志会跟主线程隔离开来。
缺点
因为webWorker跟主线程隔离,跟主线程通过消息传递来通信,可能会有一定性能开销。
webWorker无法访问DOM和一些浏览器的API,主要用于计算任务 或者网络请求。
过多的webWorker会占用过多的内存
使用
- 双方通过消息机制来进行通信, 之间的消息传递是进行的深拷贝值的传递。
js
// 主线程
const worker = new Worker('worker.js');
// 向webworker发送消息
worker.postMessage('hello i am main thread');
// 接收webworker的消息
worker.onmessage = function(event) {
console.log(event.data);
}
// worker.js
self.onmessage = function(event) {
console.log(event.data);
self.postMessage('hello2');
}
- 监听错误信息
web worker 提供两个事件监听错误,error 和 messageerror。这两个事件的区别是:
- error 当worker内部出现错误时触发
- messageerror 当 message 事件接收到无法被反序列化的参数时触发
- 关闭worker线程
主线程关闭worker worker.terminate()
Worker内部关闭 self.close()
无论是主线程还是worker线程关闭连接,都会在执行完当前一轮的worker中的EventLoop中的任务,不同的是当主线程关闭的连接时,会导致worker线程Eventloop中的postMessage的消息无法到达主线程。但是假如worker线程关闭,就可以到达。
js
// worker关闭
self.onmessage = function(e) {
console.log("开始关闭");
self.close();
// 这条消息仍然能发送到主线程
self.postMessage("关闭过程中的消息");
setTimeout(() => {
// 下一轮Event Loop的这条消息不能发送
self.postMessage("下一轮循环消息");
}, 0);
queueMicrotask(() => {
// 当前Event Loop的这条消息会发送
self.postMessage("可以到达的消息");
});
};
js
// 主线程关闭
const worker = new Worker('worker.js');
// 接收worker消息
worker.onmessage = function(e) {
worker.terminate()
};
//worker线程
self.onmessage = function(e) {
self.postMessage("发送消息");
console.log("已经关闭");
// 这条消息不能发送到主线程
self.postMessage("关闭过程中的消息");
setTimeout(() => {
// 下一轮Event Loop的这条消息不能发送
self.postMessage("下一轮循环消息");
}, 0);
queueMicrotask(() => {
// 当前Event Loop的这条消息不能发送
self.postMessage("可以到达的消息");
});
};
使用场景
- 大文件分片上传 秒传的哈希计算
- JSON解析 复杂数学计算
- 图像处理 音频处理
- 预加载和预处理资源 http请求的回调可能阻塞UI(图片加载的后续错误捕获和图片处理)
- IndexDB操作(大量数据的清理,设置)
实战
- 大文件分片
- 秒传的哈希计算
sharedWorker
可以用于iframe中的数据保持一致。