本文是贴上文中所有的代码
代码部分我就直接上代码了。文中的逻辑代码可以自己举一反三适当更改即可
// 处理worker发消息用
countDown.js
import Worker from './count.worker';
const worker = new Worker();
// 初始化倒计时
export function initCount() {
worker.postMessage({
type: 'init',
data: {},
});
}
// 暂停时间
export function pauseTime(data) {
worker.postMessage({
type: 'pause',
data,
});
}
// 清除计时器
export function clearTimer() {
worker.postMessage({
type: 'clear',
data: {},
});
}
// 移除worker
export function removeWorker() {
worker.terminate();
}
// 根据接口返回的时间校准考试剩余时间
export function alignTime(data) {
worker.postMessage({
type: 'align',
data,
});
}
// 开启倒计时
export function startCount (data) {
worker.postMessage({
type: 'start',
data,
});
}
// 获取worker
export function getWorker () {
return worker;
}
// worker文件,里面在worker线程中执行我们的倒计时
count.worker.js
const countObj = {
// 存储settimeout
timer: null,
// 剩余倒计时时间
examTime: -1,
// 倒计时是否暂停的标识
stopTimeStatus: false,
setTimer(data) {
this.timer = data;
},
setExamTime(data) {
this.examTime = data;
},
setStopTimeStatus(data) {
this.stopTimeStatus = data;
},
getTimer() {
return this.examTime;
},
getExamTime() {
return this.examTime;
},
getStopTimeStatus() {
return this.stopTimeStatus;
}
};
function countDown() {
if (countObj.timer) {
return;
}
if (countObj.timer === 0) {
postMessage(['timeEnd', 0]);
return;
}
// const start = new Date().getTime();
countObj.timer = setTimeout(() => {
countObj.timer = null;
if (!countObj.getStopTimeStatus()) {
countObj.setExamTime(countObj.getExamTime() - 1);
}
// const end = new Date().getTime();
// console.log('误差', end - start);
postMessage(['countDown', countObj.getExamTime()]);
countDown();
}, 1000);
}
onmessage = function (e) {
const {
data: { type, data },
} = e;
switch (type) {
case 'start':
countObj.setExamTime(data);
countDown();
break;
case 'align':
countObj.setExamTime(data);
postMessage(['alignTime', data]);
break;
case 'pause':
countObj.setStopTimeStatus(data);
break;
case 'init':
countObj.setTimer(null);
countObj.setExamTime(-1);
countObj.setStopTimeStatus(false);
break;
case 'clear':
clearTimeout(countObj.timer);
countObj.setTimer(null);
break;
default:
break;
}
};
home.vue
import * as countDownInstance from '../utils/countDown';
mounted() {
// 开始倒计时
countDownInstance.startCount(this.examTime);
const worker = countDownInstance.getWorker();
worker.onmessage = async (event) => {
const { data } = event;
const [type, time] = data;
if (type === 'countDown') {
this.examTime = time;
}
if (type === 'timeEnd') {
await this.autoSubmitPaper();
this.$message.warning('时间已结束');
this.examTime = time;
}
};
}
然后别忘了找个时机把worker给终止掉, 使用worker.terminate