我有一个像这样的循环
var lastUpdateTime = (new Date()).getTime(),
diffTime = 0,
i = 0;
function update() {
var updateTime = 1000 / 60,
now;
// do some stuff...
console.log("update");
console.log(" - i:" + i);
now = (new Date()).getTime();
diffTime = now - lastUpdateTime;
lastUpdateTime = now;
console.log(" - - before diffTime:" + diffTIme);
while (diffTime >= updateTime) {
diffTime -= updateTime;
}
console.log(" - - after diffTime:" + diffTime);
updateTime -= diffTime;
console.log(" - - updateTime:" + updateTime);
if ( i < 10) {
i += 1;
setTimeout(update, updateTime);
}
}
调用setTimeout时,更新diffTime时似乎没有传递updateTime期间传递的时间。在这里,我将其设置为1000 / 60
毫秒,但是我得到的数字少于那个,这没有意义。它应该大于或等于。为什么这样做?
回应davin:
我不使用setInterval
,因为它会堆叠调用http://bonsaiden.github.com/JavaScript-Garden/#other.timeouts。
while
将diffTime缩减为1000 / 60
个时间段,特别是当它大于16毫秒时。模数算子很昂贵。
我知道updateTime
未通过的原因是在我操作它之前打印出diffTime
。该数字始终低于updateTime
的{{1}}。
日志:
setTimeout
查看update
- i:0
- - before diffTime:1
- - after diffTime:1
- - updateTime:15.666666666666668
update
- i:1
- - before diffTime:12
- - after diffTime:12
- - updateTime:4.666666666666668
update
- i:2
- - before diffTime:54
- - after diffTime:3.999999999999993
- - updateTime:12.666666666666675
update
- i:3
- - before diffTime:13
- - after diffTime:13
- - updateTime:3.666666666666668
update
- i:4
- - before diffTime:11
- - after diffTime:11
- - updateTime:5.666666666666668
update
- i:5
- - before diffTime:14
- - after diffTime:14
- - updateTime:2.666666666666668
和updateTime
,时机没有意义。例如,我有before diffTime
,但是15.666666666666668
之后的时间差异。
新记录:
12
这是另一个仅在第一个刻度上不执行此操作的日志。当我测试它时,它似乎像updateWithoutTimer
- i:0
- - before diffTime:2
- - after diffTime:2
- - updateTime:14.666666666666668
updateWithoutTimer
- i:1
- - before diffTime:5
- - after diffTime:5
- - updateTime:11.666666666666668
updateWithoutTimer
- i:2
- - before diffTime:8
- - after diffTime:8
- - updateTime:8.666666666666668
updateWithoutTimer
- i:3
- - before diffTime:86
- - after diffTime:2.66666666666665
- - updateTime:14.000000000000018
updateWithoutTimer
- i:4
- - before diffTime:24
- - after diffTime:7.333333333333332
- - updateTime:9.333333333333336
updateWithoutTimer
- i:5
- - before diffTime:34
- - after diffTime:0.6666666666666643
- - updateTime:16.000000000000004
updateWithoutTimer
- i:6
- - before diffTime:24
- - after diffTime:7.333333333333332
- - updateTime:9.333333333333336
updateWithoutTimer
- i:7
- - before diffTime:27
- - after diffTime:10.333333333333332
- - updateTime:6.333333333333336
updateWithoutTimer
- i:8
- - before diffTime:14
- - after diffTime:14
- - updateTime:2.666666666666668
updateWithoutTimer
- i:9
- - before diffTime:2
- - after diffTime:2
- - updateTime:14.666666666666668
updateWithoutTimer
- i:10
- - before diffTime:2
- - after diffTime:2
- - updateTime:14.666666666666668
一样工作,所以没有经过毫秒。延迟似乎是浏览器。目前我使用的是Mozilla Aurora 6.0a和Google Chrome 14.0.803 dev。
我以为我会重新检查两个浏览器,我在Aurora中得到相同的结果,但Chrome按预期工作。奇怪的是,我事先测试了它并且它无法正常工作。我认为这是Aurora中的一个错误。我已经向mozilla提交了一份错误报告。
我指定了lastTimeUpdate,因为我想知道到达这个帧需要多长时间以及帧已经花了多长时间,所以我可以相应地处理它。
更新
以下是错误报告:https://bugzilla.mozilla.org/show_bug.cgi?id=668765。显然,setTimeout(func)
会尝试做正确的事情。如果它最近被解雇,它会尽早开火。
答案 0 :(得分:1)
你的代码对我没有多大意义。 while
循环在做什么?为什么不在舍入后只使用模数运算符并在一步中完成?你为什么以这种奇怪的方式减去这种差异?在什么基础上你声称时间还没有过去?我看不到任何价值的检查。
当然,您获得的值为<= updateTime = 1000/60 ~ 16
,因为您将时间间隔设置为:您循环到diffTime < updateTime
然后执行新计时器延迟updateTime - diffTime
。数学很简单:0 < updateTime - diffTime < updateTime
。
看起来你想要经常更新。这就是他们发明setInterval
的原因。你正在重新发明轮子,这比浏览器的实现更加不必要且不太可靠。
<强>更新强>
我认为你不是一个汇编程序员。模数运算符将执行恒定数量的算术运算,例如4个最坏情况。你的循环将执行几乎相同数量的操作每次迭代,因为它必须执行条件检查,减法,赋值和分支(这本身可能很昂贵)。因此,如果你的循环甚至进行了2次迭代,那么它已经比模数运算符更昂贵了。
关于你的时间,你说它“一直”发生,虽然从那个输出看起来它只是第一次发生。我运行相同的代码,数字是有道理的。你在运行什么平台?除了第一次打勾之外,这会不会发生?第一次打勾时是否每次都会发生?更多信息会有所帮助。
顺便说一下,你高估了diffTime
因为你在做一大堆事情之前设置了lastUpdateTime
。您应该做的是在lastUpdateTime
点分配setTimeout
。