如果想知道为什么settimeout和setinterval倒计时不准确可以先百度了解一下event loop 再来阅读效果更好
我的环境:
"vue": "^2.6.11",
"@vue/cli-plugin-babel": "~5.0.4",
"@vue/cli-service": "~5.0.4",
yarn add worker-loader -D
我的版本是"worker-loader": “^3.0.8”
vue.config.js
// 解决打包的时报错
parallel: false,
chainWebpack: (config) => {
// set worker-loader
config.module
.rule('worker')
.test(/\.worker\.js$/)
.use('worker-loader')
.loader('worker-loader')
.options({
inline: 'fallback',
filename: 'workerName.[hash].worker.js',
})
.end();
// 解决:worker 热更新问题
config.module.rule('js').exclude.add(/\.worker\.js$/);
// 删除splitChunks 请勿删除
config.optimization.delete('splitChunks');
config.plugin('define').tap((args) => {
const [define] = args;
Object.assign(define, {
IS_APPLET: JSON.stringify(true),
UNIQUE_MARK: JSON.stringify(uniqueMark),
});
return args;
});
},
好,引入工作已经完成了,其次我们需要新建一个worker文件先写一个onmessage测试
***.worker.js
// 创建存放数据的obj
const countObj = {
timer: null,
examTime: -1,
stopTimeStatus: false,
setTimer(data) {
this.timer = data;
},
setExamTime(data) {
this.examTime = data;
},
setStopTimeStatus(data) {
this.stopTimeStatus = data;
},
};
function countDown(time) {
countObj.examTime = time;
if (countObj.timer) {
return;
}
// 倒计时结束后传递出timeEnd的消息
if (time === 0) {
postMessage(['timeEnd', 0]);
return;
}
countObj.timer = setTimeout(() => {
countObj.timer = null;
countObj.examTime--;
// 传递给vue文件倒计时后的时间
postMessage(['countDown', countObj.examTime]);
countDown(countObj.examTime);
}, 1000);
}
onmessage = function (e) {
const {
data: { type, data },
} = e;
console.log('收到消息了', e);
countDown(data);
};
为了操作方便,我写了一个专门管理worker交互的js文件
***.js
import Worker from './***.worker.js';
const worker = new Worker();
// 初始化
export function init() {
worker.postMessage({
type: 'init',
data: 'test',
});
}
// 获取worker
export function getWorker () {
return worker;
}
//...还有一些方法就不细展示了, 都是关于时间的操作
如上面代码块,postMessage是向worker线程传递信息,然后可以被worker.js中的onmessage获取到。
%重点%
worker的引入方式
import Worker from './***.worker';
const worker = new Worker();
在我们配置好worker-loader之后可以使用这样的方式进行构造worker
***.vue
// 引入刚才写的引入worker的js文件
import * as countDownInstance from '../utils/***.js';
// 创建worker并传入初始时间
countDownInstance.startCount(this.time);
const worker = countDownInstance.getWorker();
worker.onmessage = (event) => {
// 做你想要的操作
const { data } = event;
const [type, time] = data;
if (type === 'countDown') {
this.time= time;
}
};