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.
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?
The real-time interval can only be greater than or equal to the value we passed. From the above code, we can see that setInterval is always inaccurate. If time-consuming tasks are added to the code, the difference will become larger and larger ( setTimeout is the same).
The clearInterval() method clears a timer set with the setInterval() method.
This is unlikely to make much of a difference though, and as has been mentioned, using setInterval with long intervals (a second is big, 4ms is small) is unlikely to have any major effects.
setTimeout allows us to run a function once after the interval of time. setInterval allows us to run a function repeatedly, starting after the interval of time, then repeating continuously at that interval.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With