使用web worker
首先安装一下worker-loader
npm i -D worker-loader
其次在vue.config.js里配置一下worker-loader
module.exports = defineConfig({
transpileDependencies: true,
chainWebpack(config) {
config.module
.rule('worker')
.test(/\.worker\.js$/)
.use('worker-loader')
.loader('worker-loader')
.end();
config.module.rule('js').exclude.add(/\.worker\.js$/)
},
})
创建一个web worker的文件 timer.worker.js
//webworks.js 监听主线程传递的 开始时间+目标时间(this.value)
self.onmessage = function(event) {
console.log("监听到的组件传过来的最终时间", event.data);
let targetDate = event.data;
// 定义一个递归函数,模拟 setInterval
function countdown() {
// 目前时间
const currentTime = Math.floor(Date.now() / 1000);
// 时间差等于,最终目标时间-当前时间
let timeDifference = targetDate - currentTime;
console.log("传给组件的最终时间和现在时间的差值", timeDifference);
// 将剩余时间发送回主线程,还剩多少时间
self.postMessage(timeDifference > 0 ? timeDifference : 0);
// 如果剩余时间小于等于0,则结束递归
if (timeDifference <= 0) {
return;
}
setTimeout(countdown, 1000);
}
// 调用递归函数
countdown();
};
组件那边首先引入worker文件
import Worker from "@/core/timer.worker.js";
在组件方法里使用
let endTime = Math.floor(Date.now() / 1000) + this.value;//这是结束时间
const worker = new Worker();//实例化worker线程
worker.postMessage(endTime);//把目标时间传到worker.js里去
// 主线程监听 Web Worker 的消息
worker.onmessage = (event) => {
console.log(event, "event");
//this.value是当前倒计时剩余时间
this.value = event.data;
console.log(this.value, "remainingTime");
//如果剩余时间结束则停止线程
//Worker线程被终止,就无法重新启动或恢复其执行。
this.getTime(this.value);
//如果倒计时减少到0了
if (!this.value) {
//你的播放提示音?或者什么的行为
worker.terminate();//最后停止worker线程
}