It seems that when I setInterval for 1000ms, it actually fires the function every 1001ms or so. This results in a slow temporal drift the longer its running.
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);
When run this shows the inaccuracy immediately.
- 0ms
- 1ms
- 2ms
- 3ms
- 4ms
- 5ms
- 5ms
- 7ms
- 8ms
- 9ms
- 9ms
- 10ms
See it for yourself: http://jsfiddle.net/zryNf/
So is there a more accurate way to keep time? or a way to make setInterval behave with more accuracy?
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/
result varies a bit but here’s a recent run:
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
accurateIntervalfunction which is a near drop in replacement forsetInterval. https://gist.github.com/1d99b3cd81d610ac7351