众所周知,JavaScript 是单线程的(帮助理解单线程)。一些复杂而又耗时的操作,势必会阻塞页面的渲染/交互,影响用户体验。web worker 允许开发者为页面额外开启一个线程,用来处理复杂而耗时的操作,不会阻塞主线程,从而达到优化用户体验的目的。
首先,我们来看一下 worker 构造函数的使用。
/**
* url: js 文件路径
* options: 配置信息
*/
const worker = new Worker(url, options)
然后,不同模块之间的通信主要通过 postMessage 进行消息推送,通过监听 onmessage 进行消息接收,实现主线程与 worker 线程之间通信。
// Demo 例子
/******* main.js *******/
const first = document.querySelector('#number1');
const second = document.querySelector('#number2');
const result = document.querySelector('.result');
if (window.Worker) {
const myWorker = new Worker("worker.js");
first.onchange = function() {
myWorker.postMessage([first.value, second.value]);
console.log('Message posted to worker');
}
second.onchange = function() {
myWorker.postMessage([first.value, second.value]);
console.log('Message posted to worker');
}
myWorker.onmessage = function(e) {
result.textContent = e.data;
console.log('Message received from worker');
}
} else {
console.log('Your browser doesn\'t support web workers.');
}
/******* worker.js *******/
onmessage = function(e) {
console.log('Worker: Message received from main script');
const result = e.data[0] * e.data[1];
if (isNaN(result)) {
postMessage('Please write two numbers');
} else {
const workerResult = 'Result: ' + result;
console.log('Worker: Posting message back to main script');
postMessage(workerResult);
}
}
在 vue 项目中,如果直接使用,首先遇到的问题是worker文件路径与打包解析的问题。
解决方案一:暴力放到 public 文件目录,使用绝对路径引入(不够优雅,通用函数代码不能够通过 import 引入,难以使用 babel 转换高级语法等)
解决方案二:使用 worker-loader ,足够优雅。
使用 worker-loader 步骤如下:
// 安装依赖包
npm install worker-loader -D
vue.config.js 完整配置:
module.exports = {
chainWebpack(config) {
// set worker-loader
config.module
.rule('worker')
.test(/\.worker\.js$/)
.use('worker-loader')
.loader('worker-loader')
.end();
// 解决:worker 热更新问题
config.module
.rule('js')
.exclude
.add(/\.worker\.js$/)
.end();
// 解决:“window is undefined”报错,这个是因为worker线程中不存在window对象,因此不能直接使用,要用this代替
config.output.globalObject('this')
},
parallel: false
}
最后,使用的时候,我们不能调用原生的worker构造函数了,需要手动 import worker 文件,然后直接实例化这个文件即可。
// demo.worker.js
import Worker from './demo.worker.js'
let worker = new Worker()
标签:web,vue,const,Worker,worker,loader,result,js
From: https://blog.csdn.net/weixin_45963880/article/details/144418991