為什麼 setInterval 在使用上時間會不太準
Why
-
JS 的 event loop 以及單執行緒機制,導致需要先將 callback 放進 callback queue 裡
-
等到 call stack 清空時才會將 callback 從 callback queue 推入 call stack
-
setInterval 會過每固定時間就把 callback 放進 callback queue, 但先前的任務可能還沒執行完,當 callback 需要花較久時間做執行時,就會導致 callback queue 裡面有多個 callback,當前面的 callback 一結束時就會馬上執行下一個 callback,如此一來也做不到間隔的效果
How
使用 setTimeout 代替 setInterval
let lastCall = Date.now();
function intervalCall() {
let now = Date.now();
let delay = now - lastCall;
lastCall = now;
console.log("interval---", delay);
setTimeout(intervalCall, 2000);
}
intervalCall();

使用 requestAnimationFrame
利用 requestAnimationFrame 讓回調在瀏覽器重繪前執行,適合動畫等場景。
let lastCall = Date.now();
function intervalCall() {
let now = Date.now();
let delay = now - lastCall;
if (delay >= 2000) {
console.log("interval---", delay);
lastCall = now;
}
requestAnimationFrame(intervalCall);
}
requestAnimationFrame(intervalCall);

另外還有
-
web worker
-
setTimer 的補償
-
setInterval 的補償