vue 中使用 web worker
# 基本使用
基本的web worker使用直接调用Worker构造函数,如下:
// url: js文件路径
// options: 配置信息
const worker = new Worker(url, options)
1
2
3
2
3
不同模块间的通信主要通过postMessage进行消息推送,通过onmessage进行消息接收,如下所示:
// a.js
let worker = new Worker('a.js')
worker.postMessage({
method: 'transferLang'
})
worker.onmessage = function (e) {
init(e.data.params)
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
// b.js
self.onmessage = ev => {
let funName = ev.data.method
if (self[funName]) {
self[funName](ev.data.params)
} else {
console.warn(`方法${funName}未定义`)
}
}
self.transferLang = function () {
let arr = []
self.postMessage({
params: arr
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 方案一
在vue项目中,如果直接使用,首先遇到的问题是worker文件路径与打包解析问题,这种首先需要安装worker-loader,解析web worker,执行以下命令即可:
npm install worker-loader -D
1
vue.config.js要添加以下配置:
module.exports = {
configureWebpack: config => {
config.module.rules.push({
test: /\.worker.js$/,
use: {
loader: 'worker-loader',
options: { inline: true, name: 'workerName.[hash].js' }
}
})
},
parallel: false, //防止打包的时候报错
chainWebpack: config => {
config.output.globalObject('this') //用this代替window
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在使用的时候,就不能调用原生的Worker构造函数了,需要手动import worker文件,然后直接实例化这个文件即可,如下所示:
// a.js
import Worker from './b.js'
let worker = new Worker()
1
2
3
2
3
# 方案二
在vue项目中,如果使用vue-worker
包:
- 安装vue-worker
npm install vue-worker
1
- 安装worker-loader
npm install worker-loader
1
vue.config.js中添加如下配置:
module.exports = {
devServer: {
open: true,
port: 3003,
},
lintOnSave: false, //关闭eslint警告
chainWebpack: config => {
config.module.rule('worker').test(/\.worker\.js$/).use('worker-loader').loader('worker-loader').options({
inline: 'fallback'
}).end();
config.module.rule('js').exclude.add(/\.worker\.js$/);
config.output.globalObject("this");
},
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
添加子线程文件test.worker.js
onmessage = function (event) {
console.log("接收到主线程发来的消息", event);
let para = JSON.parse(event.data);
countDown(para)
}
function countDown() {
for (let i = 0; i < 10; i++) {
postMessage({
value: i
});
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
worker使用
import testWorker from "../worker/test.worker.js";
mounted() {
this.initWorker();
this.noWorker();
},
methods: {
initWorker() {//使用了webworker
let _this = this;
let worker = new testWorker();
worker.name = "worker" + name;
worker.postMessage(JSON.stringify({ statu: "start" }));
setTimeout(() => {
console.log("initWorker1");
}, 0);
worker.onmessage = function (event) {
console.log("onmessage", event.data.value);
};
//打印结果:先输出定时器里面的数据,再输出for循环里面的数据
},
noWorker() {//未使用webworker
setTimeout(() => {
console.log("initWorker2");
}, 0);
for (let i = 0; i < 10; i++) {
console.log(i);
}
//打印结果:先输出for循环里面的数据,再输出定时器里面的数据
},
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
上次更新: 2024/01/30, 00:35:17
- 02
- Node与GLIBC_2.27不兼容解决方案08-19
- 03
- Git清空本地文件跟踪缓存08-13