【问题标题】:Javascript setTimeout and frame rateJavascript setTimeout 和帧速率
【发布时间】:2012-05-31 21:50:15
【问题描述】:

我似乎在 javascript 中使用帧率计数器得到了一些意想不到的结果。直到最近,计数器一直很好,我的小 js 应用程序一直在以 30fps 的速度运行。

它使用 setTimeout()(通过时间调整来应对系统“落后”)。

window.requestAnimFrame = (function() 
{
    return function (callback) {
        time += FPS;
        Heartbeat._eTime = (new Date().getTime() - Heartbeat._start);
        var diff = Heartbeat._eTime - time;

        Heartbeat._delta = FPS - diff;
        Heartbeat._deltaS = Heartbeat._delta / 1000;

        window.setTimeout(callback, FPS - diff);
    };
})();

心跳只是一个包含帧率信息的对象。

*这是我的问题:*

_MainLoopHandler: function () {

    timer = new Date().getTime();
    counter = timer;

    while (this._messages.length > 0 && (counter - timer) < 5)
    {
        // process messages from _messages array
    }

    counter = new Date().getTime();
    // THE ABOVE IS HAPPY AT 30 FPS


    while ((counter - timer) < 6) {
        1 + 1;
    }
    // THE ABOVE WHILE IS VERY UNHAPPY :(

}

所以上面的代码块是每 33.33 毫秒(30 fps)从 setTimeout 调用的函数。如果我在循环中取底部,FPS 计数器将愉快地保持在 30fps。但是,如果我把它留在里面,FPS 计数器就会发疯。它上升到 200FPS 300FPS 然后突然变为 -200FPS -10FPS 0.01FPS。它完全脱离了墙壁。 while 循环每个“帧”只能运行 10 次。

另请注意,硬编码值 5 和 6 只是检查处理循环时是否经过了 5 或 6 毫秒(用于负载平衡)。

这仅仅是 javascript 无法处理大量信息还是其他人有类似的问题。

谢谢!

【问题讨论】:

    标签: javascript loops settimeout frame-rate


    【解决方案1】:

    我真的不知道发生了什么,但我认为你应该使用局部变量来控制你的时间,不断地重新评估 counter 并一次处理 1 条消息。另外,我不太明白最后一个循环(我还重命名了变量):

    _MainLoopHandler: function () {
    
      var start = new Date().getTime();
      var current;
    
      do {
        if (this._messages.length === 0) break;
        // process 1 message
        current = new Date().getTime();
      } while (current - start < 5);
    
    }
    

    您还可以将 timing 关注点封装在一个对象(未显示)中以简化代码:

    _MainLoopHandler: function () {
    
      var timing = new Timing();
    
      do {
        if (this._messages.length === 0) break;
        // process 1 message
      } while (timing.elapsed() < 5);
    
    }
    

    【讨论】:

    • 最后一个循环只是一个“做某事”的例子。在我更新的代码中,它实际上逐个节点处理 SVG 的流式传输(所以我只在每个循环上逐位构建 SVG)。尽管如此,我还是发现了问题所在,这与我生成帧速率计数器的方式有关。
    • 但是,您上面的代码比我的代码要好,所以我已经这样做了!
    猜你喜欢
    • 1970-01-01
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多