首先看一下webpack,我用的是webpack5,需要安装worker-loader并添加配置
resolve: {
fallback: 'this'
},
output: {
globalObject: 'this'
},
module: {
rules: [
{
test: /\.worker\.js$/,
use: {
loader: 'worker-loader',
options: {
inline: true
}
}
]
}
接下来是worker的内容,由于功能需求,计算需要带一些参数,所以传入的数据是个json对象,由于传的对象里包括了大体量的数据,所以使用转移数据(Transferable Objects),使得数据快速的传给worker,它需要是一个ArrayBuffer,所以我们使用TextEncoder和TextDecoder做下数据的转换
// 业务方法中
import SelfWorker from "./selfWorker.worker";
let worker = null;
const createWorker = () => {
if (!worker) {
worker = new SelfWorker();
worker.onmessage = (e) => {
const resJson = JSON.parse(new TextDecoder('utf-8').decode(new Uint8Array(e.data)));
console.log('接收到计算结果', resJson)
}
const message = {
// 大体量数据
// ...
};
const buf = new TextEncoder('utf-8').encode(JSON.stringify(message)).buffer;
selfWorker.postMessage(buf, [buf]);
}
}
// selfWorker.worker.js
onmessage = function (e) {
// 将ArrayBuffer转为json
const jsonData = JSON.parse(new TextDecoder('utf-8').decode(new Uint8Array(e.data)));
// 执行计算操作
// ......
const res = {
data: result
id: jsonData.id
}
// 将json转为ArrayBuffer
const buf = new TextEncoder('utf-8').encode(JSON.stringify(res)).buffer;
postMessage(buf, [buf]);
}
这方面也要考虑下eventloop相关,postmessage是宏任务,实际业务下可能要避免一些阻塞的情况