Web worker
Web Worker 是 HTML5 标准的一部分,这一规范定义了一套 API, 允许我们在 js 主线程之外开辟新的 Worker 线程,并将一段 js 脚本运行其中,它赋予了开发者利用 js 操作多线程的能力。
使用
创建 worker
const work = new Worker(path, options)
path: 有效的脚本地址,必须遵守同源策略option.type可以指定worker类型,可以是classic(默认) 和moduleoption.credentials可以指定worker的凭证option.name表示worker的scope的一个DOMString值
js 主线程与 worker 线程数据传递
主线程和 worker 线程都是通过 postMessage 方法来发送消息,以及通过监听 message 事件来接受消息:
javascript
// main.js
const myWorker = new Worker("/worker.js");
myWorker.addEvenListener("message", (e) => {
console.log(e.data);
});
// or
myWorker.onmessage = (e) => {
console.log(e.data);
};
myWork.postMessage("Hello, world [from main.js]");
// worker.js
self.addEvenListener("message", (e) => {
console.log("e.data");
self.postMessage("Hello, world [from worker.js]");
});监听错误信息
web worker 提供两个事件监听错误,error 和 messageerror
error: 当worker内部出现错误时触发messageerror: 当message事件接收到无法被反序列化的参数时触发
javascript
// main.js
myWorker.addEvenListener("error", (err) => {
console.log(err.message);
});
myWorker.addEvenListener("error", (err) => {
console.log(err.message);
});
// worker.js
self.addEvenListener("error", (err) => {
console.log(err.message);
});
self.addEvenListener("error", (err) => {
console.log(err.message);
});关闭 worker 线程
javascript
// main.js
myWorker.terminate();
// worker.js
self.close();无论是主线程关闭,还是 woker 线程内部关闭,worker 线程当前的事件循环 (Event Loop) 中的任务会继续执行。下一个事件循环的任务会直接被忽略
区别在于:
- 主线程关闭,主线程 与
worker线程之间的连接会被立刻停止,主线程不会再接收到worker线程当前事件循环发送的信息 - 在
worker线程中关闭,不会直接断开与主线程的连接,而是等worker线程中当前的事件循环所有任务执行完再关闭。主线程还能收到worker线程通过postMessage()发送的信息
worker 线程中引用其他 js 文件
javascript
// utils.js
const add = (a, b) => a + b;
// worker.js
importScript("./utils.js");
console.log(add(1, 2));ESModule 模式:项目的 js 文件采用 ESModule 模式时,创建 worker 时采用 module 方式
javascript
// main.js
const worker = new Worker("/worker.js", {
type: "module",
});
// worker.js
import add from "./utils.js";
self.addEvenListener("message", (e) => {
postMessage(e.data);
});
add(1, 2);
export default self; // 把顶级对象 self 暴露出去主线程和 worker 线程可以传递哪些数据
postMessage() 传递的数据可以是由结构化克隆算法处理的任何值或 JavaScript 对象,包括循环引用。
不能处理的数据
Error和Function对象DOM 节点- 对象的某些特定参数不会被保留:
RegExp对象的lastIndex字段;属性描述符,setters,getters - 原型链上的属性也不会被追踪以及赋值
支持的数据类型
- 所有原始类型 (
symbols除外) Boolean对象,String对象,Date对象,RegExp对象BlobFileFileListArrayBufferArrayBufferViewImageDataArrayObjectMap,Set