Solution to problem with inaccurate setInterval timer

  • 2020-03-30 02:53:00
  • OfStack

If you are going to use in the js bottom setInterval, timing, and other functions, is often inaccurate, because setInterval callback function is not executed immediately after then, but the system computing resources such as idle down. And the next trigger time is in the setInterval timing starts only after the callback function has been completed, so if setInterval executed within calculation is too time consuming, or have other time-consuming tasks in execution, setInterval timer will be more and more, the delay is very severe.

The following code illustrates this
 
var startTime = new Date().getTime(); 
var count = 0; 
//Time-consuming tasks
setInterval(function(){ 
var i = 0; 
while(i++ < 100000000); 
}, 0); 
setInterval(function(){ 
count++; 
console.log(new Date().getTime() - (startTime + count * 1000)); 
}, 1000); 

The code outputs the setInterval firing time and the number of milliseconds delayed when the setInterval should fire correctly
 
176 
340 
495 
652 
807 
961 
1114 
1268 
1425 
1579 
1734 
1888 
2048 
2201 
2357 
2521 
2679 
2834 
2996 
...... 

You can see that the delays are getting worse and worse.

In order to use the relatively accurate timing function in js, we can
 
var startTime = new Date().getTime(); 
var count = 0; 
setInterval(function(){ 
var i = 0; 
while(i++ < 100000000); 
}, 0); 
function fixed() { 
count++; 
var offset = new Date().getTime() - (startTime + count * 1000); 
var nextTime = 1000 - offset; 
if (nextTime < 0) nextTime = 0; 
setTimeout(fixed, nextTime); 

console.log(new Date().getTime() - (startTime + count * 1000)); 
} 
setTimeout(fixed, 1000); 

The code corrects the delay of the current trigger by subtracting the difference between the current time and the exact time by 1000(that is, the cycle time).

Here is the output
 
186 
200 
230 
271 
158 
899 
900 
899 
900 
899 
899 
899 
902 
899 
418 
202 
232 
266 
145 
174 
192 
214 
242 
268 
149 
179 
214 
...... 

It can be seen that although the trigger time is not absolutely accurate, there is no error accumulation due to the timely correction of each trigger.

Related articles: