setTimeout、setInterval 属于定时触发器线程属于 macrotask,它的回调会受到GUI渲染、事件触发、http请求、等的影响。所以这两个不适合做精准的定时。最好的方法是定时矫正,用 new Date(targetDate:Date - new Date ) 格式化成你需要的时分秒即可。
-
setTimeout、setInterval 等 timer 的执行时间点会受到js同步代码、microtask、ui rendering等的影响,导致设置的delay expired之后无法马上执行;
-
timer有 节流(throttle) 机制,可以去mdn详细了解下。总之,不要依赖 timer 去做准确的计时计算。PS: 深入使用setTimeout等方法前建议先了解下event loop机制。
重点就是你的 setTimeout 回调函数执行的时机,比较说倒计时,每次我们的回调函数执行时,都要获取当前时间,与函数执行完毕之后的时间,它们两个时间的差就是你的函数执行时间,然后再用 1s 减去函数执行时间,就是下次 setTimeout 执行的时机;
不建议用setInterval,假如函数执行时间较长,则会跳过一次执行。建议用setTimeout递归的方式实现
start = (new Date()).getTime()
setTimeout(() => {
b = undefined;
for(var a = 0 ; a < 10000 ; a++) {
b = a;
}
end = (new Date()).getTime()
excuTime = end - start;
console.log('excuTime: ', excuTime) // 输出:1003
}, 1000)
下次 setTimeout 的执行时机应该时 1000-excuTime ,通过这样不断修正,来达到尽量的精准性。
倒计时 计算时间差(服务器获取时间)
this.nowDate = Math.floor((new Date().getTime()) / 1000) * 1000 或 res.data.second * 1000 (服务器获取的10位时间戳)
handleCountTime() {
clearTimeout(this.timer)
const t1 = Date.now()
let c1 = 0 // 递归次数
const interval = 1000 // 间隔
const sellStartTime = this.goodsDetail.sellStartTime // 售卖开始时间
if (!sellStartTime) return null
// let nowDate = this.systemTime
// if(sellStartTime < nowDate) return false
var timeDifference = parseInt(sellStartTime - this.nowDate) // 相差的总秒数
const twentyFour = 24 * 60 * 60 * 1000
if (timeDifference > twentyFour) return null
this.countdown.h = Math.floor(timeDifference / 1000 / 60 / 60 % 24)
this.countdown.m = Math.floor(timeDifference / 1000 / 60 % 60)
this.countdown.s = Math.floor(timeDifference / 1000 % 60)
this.countdown.h = this.countdown.h < 10 ? '0' + this.countdown.h : this.countdown.h
this.countdown.m = this.countdown.m < 10 ? '0' + this.countdown.m : this.countdown.m
this.countdown.s = this.countdown.s < 10 ? '0' + this.countdown.s : this.countdown.s
if (timeDifference < 0) {
this.showCountdown = false
if (this.goodsDetail.sellStatus === 0) { // 改变页面状态
this.goodsDetail.sellStatus = 1
}
clearTimeout(this.timer)
} else if (timeDifference === 0) {
this.showCountdown = true
if (this.goodsDetail.sellStatus === 0) {
this.goodsDetail.sellStatus = 1
}
this.nowDate += 1000
// 计算误差
const offset = Date.now() - (t1 + c1 * interval)
const nextTime = interval - offset
c1++
this.timer = setTimeout(this.handleCountTime, nextTime)
} else {
this.showCountdown = true
this.nowDate += 1000
// 计算误差
const offset = Date.now() - (t1 + c1 * interval)
const nextTime = interval - offset
c1++
this.timer = setTimeout(this.handleCountTime, nextTime)
}
}
获取本地 new Date() 的方法详见 https://www.cnblogs.com/lisaShare/p/11164541.html
标签:const,--,timer,js,countdown,Date,setTimeout,1000 From: https://www.cnblogs.com/lisaShare/p/12830783.html