【问题标题】:How can I make goog.Timer be more precise?我怎样才能让 goog.Timer 更精确?
【发布时间】:2012-08-02 13:50:10
【问题描述】:

我用new goog.Timer(1) 制作了一个goog.Timer 对象(http://closure-library.googlecode.com/svn/docs/class_goog_Timer.html),通过监听tick 事件每毫秒运行一个函数。但是,该函数似乎每 100 毫秒运行一次。

我假设我的函数需要一段时间才能运行(当然 javascript 是单线程的),所以需要一段时间才能进入下一轮。因此,我将计时器的间隔设置为 100,并且它每 1/10 秒可靠地运行一次。

Google Closure 库是否有一个更可靠的计时器,它只在间隔精确地运行一个函数?如果没有足够的时间在一个周期内运行一个函数,我可以取消前一个调用并在下一次分派滴答时运行它。

【问题讨论】:

  • goog.Timer 包装了原生 setInterval,它本身可能不够快,无法在 1 毫秒内运行您的函数。你确定你需要那么多粒度吗? 1ms 轮询是残酷的。不能用goog.events.listen和dispatchEvent吗?
  • 谢谢,我不需要 1ms 的粒度。不过 20-100 毫秒就好了。

标签: timer google-closure google-closure-library


【解决方案1】:

Nicholas Zakas 在他的博客上写了一篇关于 Timer resolution in browsers 的精彩总结。正如 Nicholas 指出的那样,HTML5 timers specification(截至 2012 年 8 月 2 日)规定setTimeout() 和setInterval() 的最小间隔为 4 毫秒。

我编写了以下演示应用程序来测试goog.Timer 的最小间隔延迟。

<!doctype html>
<html>
<head>
  <title>goog.Timer Test</title>
  <script src="../closure-library/closure/goog/base.js"></script>
</head>
<body>

<h1>goog.Timer Test</h1>

<div id="mainContent"></div>

<script>
  goog.require('goog.Timer');
</script>
<script>
  var tickCount = 0;
  var timer = new goog.Timer(1);
  var mainDiv = document.querySelector('#mainContent');

  /**
   * Tick callback.
   */
  var tickCounter = function() {
    tickCount++;
    if (tickCount % 1000 === 0) {
      var timeElapsed = goog.now() - startTime;
      mainDiv.innerHTML = 'goog.Timer tick events: ' + tickCount +
          '<br>actual elapsed milliseconds: ' + timeElapsed +
          '<br>milliseconds per goog.Timer tick: ' + timeElapsed/tickCount;
    }
  };

  startTime = goog.now();
  timer.start();
  goog.events.listen(timer, goog.Timer.TICK, tickCounter);
</script>
</body>
</html>

在 Chrome 版本 21 中运行此程序始终显示每个 goog.Timer 滴答事件大约 4.2 毫秒,这非常接近 4 毫秒的最小允许浏览器计时器分辨率。

【讨论】:

    【解决方案2】:

    我不知道 goog 计时器,但这在我的模拟器中有效。在我告诉它之后它停止了 3 毫秒。

    public Timer gameTimer;
    int i = 1;
    TextView TVsource;//You still have to assign this to a layout view in onCreate
    
    public void runTimer() {
    
        gameTimer = new Timer();
        gameTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (i < 5000) {
                    TimerMethod();
                }
            }
        }, 1000, 1);
    }
    
    public void TimerMethod() {
        this.runOnUiThread(Timer_Tick);
    }
    
    private Runnable Timer_Tick = new Runnable() {
        public void run() {
            i++;
            TVsource.setText("its " + i);
        }
    };
    

    附:我刚刚意识到这是一个javascript问题,但到底是什么?试试看。

    【讨论】:

      猜你喜欢
      • 2017-09-07
      • 2011-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-22
      • 1970-01-01
      • 1970-01-01
      • 2018-12-25
      相关资源
      最近更新 更多