Will Setinterval Drift

Will setInterval drift?

Here's a benchmark you can run in Firefox:

var start = +new Date();
var count = 0;
setInterval(function () {
console.log((new Date() - start) % 1000,
++count,
Math.round((new Date() - start)/1000))
}, 1000);

First value should be as close to 0 or 1000 as possible (any other value shows how "off the spot" the timing of the trigger was.) Second value is number of times the code has been triggered, and third value is how many times the could should have been triggered. You'll note that if you hog down your CPU it can get quite off the spot, but it seems to correct itself. Try to run it for a longer period of time and see how it handles.

setInterval timing slowly drifts away from staying accurate

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

setInterval is not run at exact interval

While no Javascript running on a standard browser claims to be real-time (as pointed out in several comments) there are steps you an take to make things not get as out of hand as it appears the example in the question does (the errors being cumulative).

Just to start with an experiment I ran this on my Windows 10 Chrome:

const startTime = new Date().valueOf();

function printElapsedTime(startTime) {
let curTime = new Date().valueOf();
console.log(curTime - startTime);
}

let intervalObj = setInterval(printElapsedTime, 1000, startTime);
<div id="show">0</div>

setInterval will become unreliable and inaccurate sometimes

setTimeout and setInterval in javascript only promise that they won't be run before the specific time. they try to execute your function as soon as possible but they sometimes can't do that. They are not timers. They are some functions that call a callback after a time which is the minimum amount of waiting before calling the callback function. Unfortunately there is not an accurate timer in javascript. you can implement it yourself.

Edit: you may ask how:

read the following thread:
https://stackoverflow.com/a/29972322/12337783

Why setInterval runs slower than expected?

All scheduled code is put in a single queue and processed by one thread. If the setInterval function can't finish faster than 10ms, the execution time will fall behind the schedule. The precise time of execution cannot be guaranteed.

How to compensate for setInterval timing drift in Javascript audio

Probably the best way to do this is to have a single, always active 1/8 note interval, then call the quarter-note every other tick:

// wrapped in a closure to allow for a private tickCount variable
// alternatively, you could use a more advanced object with start/stop methods, etc.
(function() {
var tickCount = 0,
tick = function() {
eighthNoteFunc();
if(tickCount %2 == 0) {
quarterNoteFunc();
}
tickCount++;
};

setInterval(tick, 300);
})();

This ensures that the methods are always called on the same tick. You can also expand this to support half notes (tickCount % 4 == 0) and whole notes (tickCount % 8 == 0).


This interested me, so I decided to create a fully-working sample (except, using animated backgrounds instead of audio): http://jsfiddle.net/SycBm/

This allows you to see the eighth-, quarter-, and half- notes ticking in sync, as well as start & stop the timer, and independently enable or disable the notes.

Enjoy!

Are there any disadvantages to using javascript setInerval with a long interval?

No, there is no disadvantage. However, the timer isn't the most accurate. See also: Will setInterval drift? This may not matter to you, as it is a bigger problem for timers fired rapidly. Plus, it doesn't soundl ike exact timing is a problem for you either.

Why are setTimeout and setInterval working differently in the browser and in Node.js?

This is because Chrome does self-correct the drift in setInterval. node (and other browsers) don't. Note that currently specs agree with node, even if there is an active discussion to follow Chrome's behavior.

So in Chrome, it's like if you had a precise

at beginTime + 200
do fn
at beginTime + 400
do fn
at beginTime + 600
do fn
...etc

while in others it will be

at beginTime + 200
do fn
at now + 200
do fn
...etc.

But we know there will always be some delay preventing the timer to fire exactly when scheduled, and so in environments without drift correction, we end up with a now that is later the expected time.

So in Chrome, the setInterval job will be in the queue before the setTimeout one, while in other environments, it will come after, because of the drift, even if infinitesimally small.



Related Topics



Leave a reply



Submit