准确的Javascript计时器

时间:2015-09-03 21:54:21

标签: javascript settimeout setinterval

我正在尝试建立一个准确的倒数计时器,显示分钟和秒数。我尝试了两种方法。方法1使用setTimer函数并计算漂移。对于该方法,一些值被跳过并且一些值被重复。方法2产生所有必要的值,但是这些值没有以均匀的间隔打印到屏幕上(在repl.it中测试)。如何制作既准确又能打印所有值的计时器?

Approach1:

 #ifdef __cplusplus
 extern "C"
 #endif
 // no block for the extern "C", so it applied only for a single function
 void funnction_name(); //a sample func.

方法2:

function countTime(duration) {
     var expected = 1;
     var secsLeft;
     var startT = new Date().getTime();
     var oneSecond = 1000;
     var expected = startT + oneSecond;

     window.setTimeout(step, oneSecond);

     function step() {
         var nowT = new Date().getTime();
         var drift = nowT - expected;

         if (drift > oneSecond) {
             console.log("drift is over 1 second long!");
         }

         console.log('drift is ' + drift);
         var msDelta = nowT - startT;
         var secsLeft = duration - Math.floor(msDelta / 1000);
         console.log("secsLeft" + secsLeft);

         if (secsLeft === 0) {
             ++count;
             console.log("cleared");

         } else {

             expected += oneSecond;
             setTimeout(step, Math.max(0, oneSecond - drift));
         }
     }
 }
 countTime(60);

2 个答案:

答案 0 :(得分:1)

function(){
  date = get the date
  curSeconds = compute the number of seconds to be displayed
  if(oldSeconds!=curSeconds) then refresh display and do  oldSeconds = curSeconds;     
}

经常调用此功能,调用的越多,计时器就越准确。我建议你使用requestAnimationFrame()而不是setTimout()它将被调用每秒60次(周期16ms),因为它是大多数显示器的刷新率,它是最大可见"准确度"。当页面不可见时,它也不会被调用。

简单,干净,长时间不漂移。

它也可以暂时不被调用。

答案 1 :(得分:1)

考虑使用requestAnimationFrame

function countTime(duration) {
    requestAnimationFrame(function(starttime) {
        var last = null;
        function frame(delta) {
            var timeleft = Math.floor(duration - (delta - starttime)/1000),
                minutes = Math.floor(timeleft/60),
                seconds = timeleft%60;
            if( timeleft > 0) {
                if( last != timeleft) {
                    console.log("Time left: "+minutes+"m "+seconds+"s");
                    last = timeleft;
                }
                requestAnimationFrame(frame);
            }
        }
        frame(starttime);
    });
}
countTime(60);

这将精确到浏览器本身的帧速率:)