在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()
无法提供。
答案 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);