单调增加JavaScript的时间?

时间:2011-09-01 15:12:34

标签: javascript timer

在JavaScript中单调增加时间的最佳方法是什么?我希望有类似Java的System.nanoTime()

Date()显然不起作用,因为它受系统时间变化的影响。

换句话说,我想要的是< = b, 总是

a = myIncreasingTime.getMilliseconds();
...
// some time later, maybe seconds, maybe days
b = myIncreasingTime.getMilliseconds();

充其量,即使在Date()中使用UTC功能,它也会返回它认为正确的时间,但如果有人向后设置时间,则下一次调用Date()可以返回较小的值。 System.nanoTime()不会受到此限制(至少在系统重新启动之前)。

修改: [2012-02-26:无意影响原有问题,有赏金]

我不知道“壁垒时间”,我有兴趣以一定的准确度知道已过去的时间,Date()无法提供。

4 个答案:

答案 0 :(得分:13)

您可以使用window.performance.now() - 自Firefox 15和window.performance.webkitNow() - Chrome 20]

var a = window.performance.now();
//...
var delay = window.performance.now() - a;

答案 1 :(得分:7)

你可以包裹Date()Date.now()以强制它是单调的(但不准确)。草图,未经测试:

var offset = 0;
var seen = 0;
function time() {
  var t = Date.now();
  if (t < seen) {
    offset += (seen - t);
  }
  seen = t;
  return t + offset;
}

如果系统时钟在给定时刻被设置,那么似乎没有时间过去(并且包含该时间间隔的经过时间将是不正确的),但是您至少不会有负增量。如果没有回退,则返回与Date.now()相同的值。

如果您正在编写游戏模拟循环,这可能是一个合适的解决方案,例如,非常频繁地调用time() - 最大错误是调用次数乘以调用间隔的次数。如果您的应用程序自然不会这样做,您可以在setInterval上明确地调用它,假设(假设系统时钟不是由系统时钟计算),以保持您的准确性为代价。 / p>


也可能将时钟设置为前进,这不会阻止单调性,但可能会产生同样不良影响(例如,游戏花费太长时间试图立即赶上其模拟)。然而,这与已经睡了一段时间的机器没有特别的区别。如果需要这样的保护,它只是意味着改变现有条件下的条件,并保持可接受进度的恒定阈值:

if (t > seen + leapForwardMaximum) {
  offset += (seen - t) + leapForwardMaximum;
}

我建议将leapForwardMaximum设置为超过1000毫秒,因为例如,Chrome(如果我没记错的话)会限制背景标签中的计时器每秒触发不超过一次。

答案 2 :(得分:4)

Javascript本身没有任何访问nanoTime的功能。您可以将一个java-applet加载到像benchmark.js那样的信息。也许@mathias可以阐明他们在那里所做的事情......

答案 3 :(得分:1)

Firefox为setTimeout提供“延迟”参数... 这是实现单调增加时间计数器的方法之一。

var time = 0;

setTimeout(function x(actualLateness) {
  setTimeout(x, 0);
  time += actualLateness;
}, 0);