问题:
- 定时器并不准时:因为 JS 是单线程执行的,如果发生阻塞会导致 setTimeout 不按期执行
- setInterval会累积执行
function demo() {
setInterval(function(){
console.log(22222)
},1000)
sleep(2000)
}
function sleep(t){
var time = Date.now()
while(Date.now() - time < t){console.log(1)}
time = Date.now()
}
demo()
可以通过 requestAnimationFrame 来实现定时器
- window.requestAnimationFrame:浏览器在下次重绘之前调用指定的回调函数更新动画(1000ms/60帧 = 16.6ms)
function setInterval(cb, time) {
var timer
var startTime = Date.now()
var endTime = Date.now()
function loop() {
timer = requestAnimationFrame(loop)
endTime = Date.now()
if (endTime - startTime >= time) {
startTime = endTime = Date.now()
cb(timer)
}
}
requestAnimationFrame(loop)
}
var a = 0
setInterval(timer => {
console.log(1)
a++
if (a === 3) cancelAnimationFrame(timer)
}, 1000)
function setTimeout(cb, time) {
var timer
var startTime = Date.now()
var endTime = Date.now()
function loop() {
timer = requestAnimationFrame(loop)
endTime = Date.now()
if (endTime - startTime >= time) {
cancelAnimationFrame(timer)
cb(timer)
}
}
requestAnimationFrame(loop)
}
setTimeout(() => {
console.log(1)
}, 1000)