Как сделать goog.Timer более точным?

Я создал объект goog.Timer (http://closure-library.googlecode.com/svn/docs/class_goog_Timer.html) с new goog.Timer(1) для запуска функции каждую миллисекунду путем прослушивания события тика. Однако вместо этого функция, казалось, работала каждые 100 миллисекунд.

Я предположил, что моей функции требуется некоторое время для запуска (и javascript, конечно, является однопоточным), поэтому потребовалось некоторое время, чтобы перейти к следующему раунду. Следовательно, я установил интервал для таймера на 100, и он надежно работал каждую 1/10 секунды.

Есть ли в библиотеке Google Closure более надежный таймер, который запускает функцию только с заданным интервалом? Если не хватает времени для запуска функции в одном цикле, я могу отменить предыдущий вызов и запустить его при следующей отправке тика.


person dangerChihuahua007    schedule 05.08.2012    source источник
comment
goog.Timer оборачивает родной setInterval, который сам по себе, вероятно, недостаточно быстр, чтобы запустить вашу функцию за 1 мс. Вы уверены, что вам нужна такая степень детализации? Опрос в 1 мс — это жестоко. Нельзя ли использовать goog.events.listen и dispatchEvent?   -  person hyperslug    schedule 05.08.2012
comment
Спасибо, мне не нужна гранулярность в 1 мс. Хотя 20-100 мс было бы неплохо.   -  person dangerChihuahua007    schedule 05.08.2012


Ответы (2)


Николас Закас написал хорошее резюме Разрешение таймера в браузерах в своем блоге. Как отметил Николас, спецификация таймеров HTML5 (по состоянию на 2 августа 2012 г.) требует, чтобы минимальный интервал для 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 постоянно показывает примерно 4,2 миллисекунды на событие goog.Timer тика, что очень близко к минимально допустимому разрешению таймера браузера в 4 миллисекунды.

person Christopher Peisert    schedule 05.08.2012

Я не знаю о таймерах Google, но это сработало в моем эмуляторе. Однако он остановился через 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);
    }
};

P.S. Я только что понял, что это вопрос javascript, но что, черт возьми? Попробуй.

person Seth Schaffner    schedule 05.08.2012