使用ts hooks封装了一个倒计时方法
有点久没有更新和维护了,最近会抽时间把之前的很多内容补上!今天先补一个倒计时的方法,通过setTimeout方法计时,这里肯定很多人会有疑问,为什么用 setTimeout 不用setInterval 呢?因为使用setInterval的话,我们都知道 setInterval 和 setTimeout 都是异步的方法并且都是宏任务,所以 他需要等待 同步任务 和 微任务执行完成后 在执行,所以等待时间 >= 设定的等待时间!
那么我们需要怎么减少时间的误差呢?可以看下我前面的写的面试题的文章!里面有写两种方式!我这边用的是其中的一种,使用动态计算的方式!具体直接上代码
import { reactive, createVNode, h } from 'vue';
import moment from 'moment';
// Seconds 需要计时的秒数 time 开始计时的时间 callback 计时结束的回调函数
export function useTimeDown(Seconds:number = 600, time: moment.MomentInput,callback?: () => void ) {
let setTime = new Date().getTime();
let count = 0;
const state = reactive({
H:'',
M:'',
S:'',
Type:false,
})
function computingTime() {
const second = Seconds - moment().diff(moment(time),'seconds')
if( !second || second<=0){
console.log('倒计时结束啦!')
callback && callback()
return
}
if(state.Type){
console.log('倒计时停止啦!')
return
}
count++;
state.H = String(parseInt((second/60/60))).length == 1? '0'+String(parseInt((second/60/60))):String(parseInt((second/60/60)))
state.M = String(parseInt((second/60))).length == 1? '0'+String(parseInt((second/60))):String(parseInt((second/60)))
state.S = String(second%60).length == 1? ('0'+String(second%60)):String(second%60)
let errTime = new Date().getTime() - (setTime + count * 1000);
let nextTime = 1000 - errTime > 0 ? 1000 - errTime : 0;
setTimeout(computingTime, nextTime);
}
setTimeout(computingTime, 1000);
return state
}
因为这边是直接使用 setTimeout 运行的 所以就没有 computingTime 暴露出来,当需要停止时,只需要把state.Type 赋值为 true即可!
调用
// 引入
import { useTimeDown } from '/@/hooks/web/useTimeDown';
// 使用 lockScreenData就获取到倒计时的时间了
// lockScreenData.H 时 lockScreenData.M分 lockScreenData.S秒
this.lockScreenData = useTimeDown(this.lockScreenSecond, this.lockScreenTime,()=>{
this.setLockScreen({type:false})
})