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
The code outputs the setInterval firing time and the number of milliseconds delayed when the setInterval should fire correctly
You can see that the delays are getting worse and worse.
In order to use the relatively accurate timing function in js, we can
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
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.
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.