一、写在前面 我们可以想象一个场景,在一些购物商场的秒杀活动中,我们会发现倒计时的时间是越来越慢,所以此时我们需要不断地进行F5 刷新,其目的就是向服务器请求最新的倒计时数据。此时我们可以思考一下,这样一种情况出现的原因是什么?这是因为我们从服务端请求到倒计时的数据之后,就在前端进行倒计时,而js又是单线程的语言,所以每一次我们使用setTimeout 和setInterval 来进行倒计时的时候,就是将其放到任务队列中,等待主线程执行完毕后执行,如果此时主线程存在大量耗时的操作,此时就会造成延时的问题。 二、解决方法
const interval = 1000
let totalTime = 20000
let count = 0
let lastTimer = new Date().getTime()
let timer = null
timer = setTimeout(func, interval)
function func() {
count++
let delaytimer = new Date().getTime() - (interval * count + lastTimer)
if (delaytimer < 0) {
delaytimer = 0
}
let nextTimer = interval - delaytimer
totalTime -= interval
console.log(`当前延迟了${delaytimer}ms, 下一次执行${nextTimer}ms, 还剩下${totalTime}ms。`)
if (totalTime <= 0) {
clearTimeout(timer)
} else {
timer = setTimeout(func, nextTimer)
}
}
上述代码的原理是:记录当前时间和理论时间之间的时间间隔,并不断对下一次定时器时间进行校正。
|