似乎当我setInterval持续1000ms时,它实际上每1001ms左右触发一次该功能.这导致运行时间越长,时间漂移越慢.
var start;
var f = function() {
if (!start) start = new Date().getTime();
var diff = new Date().getTime() - start;
var drift = diff % 1000;
$('<li>').text(drift + "ms").appendTo('#results');
};
setInterval(f, 1000);
Run Code Online (Sandbox Code Playgroud)
运行时,立即显示不准确.
亲眼看看:http://jsfiddle.net/zryNf/
那么有更准确的方法来保持时间吗?还是一种setInterval更准确的表现方式?
Ale*_*yne 14
我想我可能已经找到了解决方案.我想,如果你可以测量它,你可以补偿它,对吧?
var start;
var nextAt;
var f = function() {
if (!start) {
start = new Date().getTime();
nextAt = start;
}
nextAt += 1000;
var drift = (new Date().getTime() - start) % 1000;
$('<li>').text(drift + "ms").appendTo('#results');
setTimeout(f, nextAt - new Date().getTime());
};
f();
Run Code Online (Sandbox Code Playgroud)
结果有所不同,但这是最近的一次运行:
0ms
7ms
2ms
1ms
1ms
1ms
2ms
1ms
1ms
1ms
Run Code Online (Sandbox Code Playgroud)
因此,如果它被调用1ms,2ms甚至晚10ms,那么下一次调用将被安排来补偿.只要每次通话都不准确,但时钟永远不会浪费时间,那么这应该运作良好.
现在我把它包装成一个全局accurateInterval函数,这个函数几乎可以替代setInterval. https://gist.github.com/1d99b3cd81d610ac7351
有一点googleing,你会看到,setInterval并且settimeout两个都不会在你告诉它的确切时间执行代码.使用setInterval(f,1000);它会在执行前等待至少1000MS,它不会等到1000MS.其他进程也在等待轮到他们使用CPU,这会导致延迟.如果你需要一个精确的计时器,时间为1秒.我会使用较短的间隔,如50MS,并将其与开始时间进行比较.我不会低于50MS,因为浏览器有最小间隔
这里有一些参考:
"为了理解定时器如何在内部工作,需要探索一个重要的概念:定时器延迟不能得到保证.由于浏览器中的所有JavaScript都在单个线程上执行,因此只运行异步事件(例如鼠标点击和定时器)当执行中有一个开放时.这最好用图表来证明,如下所示:"取自:http://css.dzone.com/news/how-javascript-timers-work
"Chrome和Chromium提供的平均间隔刚好超过41毫秒,第二个时钟的差异足以在一分钟内显着降低.Safari的亮度不到41毫秒,表现优于Chrome,但仍然不是很好.我在Windows XP下读取了这些读数,但Chrome实际上在Windows 7下表现更差,平均间隔约为46毫秒." 取自:http: //www.goat1000.com/2011/03/23/how-accurate-is-window.setinterval.html
| 归档时间: |
|
| 查看次数: |
10610 次 |
| 最近记录: |