I think I may have figured out a solution. I figured, if you can measure it you can compensate for it, right?
http://jsfiddle.net/zryNf/9/
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();
result varies a bit but here's a recent run:
0ms
7ms
2ms
1ms
1ms
1ms
2ms
1ms
1ms
1ms
So if it gets called 1ms, 2ms or even 10ms later than it should the next call is scheduled to compensate for that. As long as inaccuracy is only per call, but the clock should never lose time, then this should work well.
And now I wrapped this up a global accurateInterval
function which is a near drop in replacement for setInterval
. https://gist.github.com/1d99b3cd81d610ac7351
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…