如何让setInterval完全每n毫秒执行一次?

时间:2017-03-29 01:51:55

标签: javascript

我正在尝试获取一段代码来执行每一秒。但是,我发现每次运行setInterval之间的时间差不超过1000毫秒。

var incrementUnitCount = function() {

    var now = new Date();

    console.log('Shift' + now + 'ms' + now.getMilliseconds());

};

setInterval(incrementUnitCount2, interval);

输出如下:

js/schedule.js (148) :ShiftTue Mar 28 2017 21:44:05 GMT-0400 (EDT)ms457
js/schedule.js (148) :ShiftTue Mar 28 2017 21:44:06 GMT-0400 (EDT)ms458
js/schedule.js (148) :ShiftTue Mar 28 2017 21:44:07 GMT-0400 (EDT)ms460
js/schedule.js (148) :ShiftTue Mar 28 2017 21:44:08 GMT-0400 (EDT)ms463
js/schedule.js (148) :ShiftTue Mar 28 2017 21:44:09 GMT-0400 (EDT)ms465
js/schedule.js (148) :ShiftTue Mar 28 2017 21:44:10 GMT-0400 (EDT)ms468
js/schedule.js (148) :ShiftTue Mar 28 2017 21:44:11 GMT-0400 (EDT)ms468
js/schedule.js (148) :ShiftTue Mar 28 2017 21:44:12 GMT-0400 (EDT)ms470
js/schedule.js (148) :ShiftTue Mar 28 2017 21:44:13 GMT-0400 (EDT)ms472

如图所示,每次通话之间的时间差是1001ms,而不是1000.如果我有一个时间敏感的应用程序,我怎么能保证每1000毫秒一次通话 - 如下所示:

js/schedule.js (148) :ShiftTue Mar 28 2017 21:44:12 GMT-0400 (EDT)ms470
js/schedule.js (148) :ShiftTue Mar 28 2017 21:44:13 GMT-0400 (EDT)ms470

谢谢!

2 个答案:

答案 0 :(得分:0)

您不能,但您可以使用requestAnimationFrame更准确(不准确)替换setInterval。来自https://gist.github.com/joelambert/1002116

window.requestInterval = function(fn, delay) {
    if( !window.requestAnimationFrame       && 
        !window.webkitRequestAnimationFrame && 
        !(window.mozRequestAnimationFrame && window.mozCancelRequestAnimationFrame) && // Firefox 5 ships without cancel support
        !window.oRequestAnimationFrame      && 
        !window.msRequestAnimationFrame)
            return window.setInterval(fn, delay);

    var start = new Date().getTime(),
        handle = new Object();

    function loop() {
        var current = new Date().getTime(),
            delta = current - start;

        if(delta >= delay) {
            fn.call();
            start = new Date().getTime();
        }

        handle.value = requestAnimFrame(loop);
    };

    handle.value = requestAnimFrame(loop);
    return handle;
}

答案 1 :(得分:0)

我最终预先计算了一个DateTime值数组,我只是检查数组的当前时间以跟踪时间。

谢谢!