0

setTimeout/setInterval实现倒计时,会出现时间点偏差,请问如何处理这种问题?

秦牧 289
2019-05-13 提问
8 个回答
1

不用累计时间,每次都用new Date()或者Date.now()取得绝对当前时间进行处理。

1

setTimeout的间隔时间不要写死,每次setTimeout的时候计算一下实际的间隔时间,从而修正下一次的间隔时间。

1

重点就是你的setTimeout回调函数执行的时机,比较说倒计时,每次我们的回调函数执行时,都要获取当前时间,与函数执行完毕之后的时间,它们两个时间的差就是你的函数执行时间,然后再用1s减去函数执行时间,就是下次setTimeout执行的时机;
不建议用setInterval,假如函数执行时间较长,则会跳过一次执行。建议用setTimeout递归的方式实现

1
  1. setTimeout等timer的执行时间点会受到js同步代码、microtask、ui rendering等的影响,导致设置的delay expired之后无法马上执行 2. timer有throttle机制,可以去mdn详细了解下。总之,不要依赖timer去做准确的计时计算。PS: 深入使用setTimeout等方法前建议先了解下event loop机制。
1

setTimeout、setInterval 属于定时触发器线程属于macrotask,它的回调会受到GUI渲染、事件触发、http请求、等的影响。所以这两个不适合做精准的定时。最好的方法是定时矫正,用new Date(targetDate:Date - new Date )格式化成你需要的时分秒即可。

0

你只要知道setTimeout和setInterval设置的时间间隔绝对不准,你就会发现无法完全100%的进行倒计时

0

什么样的情景需要用到这么精确的倒计时?

0
function countDown(){
    // todo ...
    const time = new Date().getTime();
    const timer = time % 1000;
    setTimeout(countDown, timer);
}
countDown();

撰写答案

推广链接