如何在Javascript中编写快速计时器?

时间:2013-02-20 14:26:18

标签: javascript browser timer setinterval

我需要一个非常快速的Javascript计时器。定时器分辨率被认为是10毫秒。我已经实现了一个工作计时器,但问题是,时间总是取决于浏览器中运行了多少其他资源。当动画GIF正在运行时,我的计时器根本不起作用。这是代码(工作!):<​​/ p>

var timer = new Timer();

function Timer(){
    var time = 0;
    //Every 10ms we are incrementing the timer:
    setInterval(function(){
        time=time+1;
    },10);
    this.getTime=function(){return time;}
}

function testTimer(){
    var counter = 0;
    var resultsum = 0;
    var everytensum = 0;
    setInterval(function(){
        counter = counter + 1;
        window.timeoutTesterRunning = true;
        var timeoutTester = new TimeoutTester();
        setTimeout(function(){
            console.log(counter+": "+timeoutTester.getResult());
            resultsum = resultsum+timeoutTester.getResult();
            console.log(resultsum);
            if(counter%10==0){
                console.log("Counting last 10 seconds: "+(resultsum-everytensum));
                console.log("Counting last "+counter+" seconds: "+resultsum);
                everytensum = resultsum;
            }
        },1200)
    }, 3000);
}

function TimeoutTester(){
    var result;
    var snap_time1 = timer.getTime();
    setTimeout(function(){
        var snap_time2 = timer.getTime();
        result = snap_time2-snap_time1;
    },1000);
    this.getResult=function(){return result;}
}

现在来自console.log的结果(总和在括号中):

[10:10:54.466] 1: 100 (100)
[10:10:57.466] 2: 100 (200)
[10:11:00.466] 3: 100 (300)
[10:11:03.466] 4: 100 (400)
[10:11:06.466] 5: 100 (500)
[10:11:09.465] 6: 100 (600)
[10:11:12.466] 7: 101 (701)
[10:11:15.467] 8: 100 (801)
[10:11:18.467] 9: 100 (901)
[10:11:21.467] 10: 100 (1001)
[10:11:21.476] Counting last 10 seconds: 1001
[10:11:24.467] 11: 100 (1101)
[10:11:27.468] 12: 100 (1201)
[10:11:30.467] 13: 100 (1301)
[10:11:33.478] 14: 60 (1361)  //Animated Gif started: Less countings! ("Time runs longer")
[10:11:36.476] 15: 57 (1418)
[10:11:39.482] 16: 58 (1476)
[10:11:42.472] 17: 61 (1537)
[10:11:45.474] 18: 56 (1593)
[10:11:48.484] 19: 48 (1641)
[10:11:51.470] 20: 55 (1696)
[10:11:51.476] Counting last 10 seconds: 695
[10:11:51.482] Counting last 20 seconds: 1696

柜台运行非常规律。但是当浏览器忙碌时(通过动画GIF),Javascript没有时间正确设置间隔。函数Timer()只是没有收到增加var time所需的时间,因此值从远到低(当我第一次开始测试时,值甚至更低,约为40,但我是能够通过使用功能实现将它们提升到~55。

有谁知道我们如何让Javascript计时器工作?或者只是不可能阻止浏览器查杀计时器?

3 个答案:

答案 0 :(得分:3)

setInterval从来没有做过计时,而是安排执行!它的间隔不可靠。如果您想进行计时,请使用Date时间戳:

function Timer(){
    var start = Date.now();
    this.getTime=function() {
        return Date.now() - start;
    }
}

这样,你获得1毫秒的分辨率。

答案 1 :(得分:0)

var timer = function(f,args){t = Date.now(); f.call(参数); console.log(Date.now() - t)}

答案 2 :(得分:0)

因为无法实现计时器,所以我得到了一个不同的解决方案,它是一种在setInterval中运行动画的强制力:

function animate(elementId,pictureTimeArrayName){
    var elementStyle = document.getElementById(elementId).style;
    var pictureTimeArray = window[pictureTimeArrayName];

    function toInterval(startDate, timeSinceStart, picture){
        var interval = setInterval(function(){
            if(Date.now()-startDate>=timeSinceStart){
                clearInterval(interval);
                elementStyle.background = "url("+picture+")";
            }
        },2);
    }

    setInterval(function(){
        var startDate = Date.now();
        for(var i=0;i<pictureTimeArray.length;i++){
            toInterval(startDate,pictureTimeArray[i].time,pictureTimeArray[i].picture);
        }
    },pictureTimeArray[pictureTimeArray.length-1].time);
}

虽然数组看起来像这样:

var array_1 = [{picture: "animations/pic_1.gif", time: "30"},
               {picture: "animations/pic_2.gif", time: "60"},
               ...
               {picture: "animations/pic_36.gif", time: "1080"},];

这看起来非常好(对于&gt; = 30 fps)。但是:当动画Gif正在运行时,它仍然不再那么流畅。如果它是一个重复的动画,图纸并不总是干净的。在一些从不浏览器的版本(来自Firefox)中,绘图甚至比旧版本更糟糕,而其他浏览器(Chrome)也存在问题。特别是如果您在Chrome中更改浏览器窗口并返回窗口:动画看起来很奇怪。

因此,您最好使用Flash或其他非Javascript解决方案来制作专业动画。