为什么setInterval中函数执行的间隔时间不准确?
答:js是单线程的,回调函数执行间隔受回调函数执行时间的影响。
setInterval中函数执行的间隔时间是怎样决定的?
结论一:setInterval中函数执行的间隔时间受回调函数执行时间的影响
结论二:第一次回调函数执行期间,当第二次定时器触发时,如果主线程有回调函数仍然在执行,则废弃第二次的回调函数,如果主线程没有回调函数在执行,则立即执行第二次回调函数。依次类推...
(具体浏览器实现的时候是不是这样,未考证,意思大概就是这样)

例子1:回调函数执行时间是150ms,而定时器间隔是100ms。
<!-- 这是一个执行时间比定的函数:执行时间是150ms -->
function fn () {
let duration = 150;
let startTime = new Date().getTime();
let i = 0;
while (new Date().getTime() - startTime <= duration) {
i++;
}
}
setInterval(function cb() {
fn();
}, 100);
打开chrome控制台查看分析结果: 从图中可以看出,原本代码想实现每隔100ms执行一次,结果却是每隔150ms执行一次。

例子2:回调函数执行时间是300ms,这期间会触发多次定时器。
<!-- 这是一个执行时间比定的函数:执行时间是300ms -->
function fn () {
let duration = 300;
let startTime = new Date().getTime();
let i = 0;
while (new Date().getTime() - startTime <= duration) {
i++;
}
}
setInterval(function cb() {
fn();
}, 100);
打开chrome控制台查看分析结果: 从图中可以看出,原本代码想实现每隔100ms执行一次,结果却是每隔300ms执行一次。

例子3:回调函数第6-10次执行时间是正常的,其他都是300ms
let count = 1;
let pre = null;
function fn () {
let duration = 300;
let startTime = new Date().getTime();
let str = '';
let i = 0;
if (count < 6 || count > 10 ) {
while (new Date().getTime() - startTime <= duration) {
i++;
}
} else {
str = '--无阻塞';
}
if (count === 20) {
clearTimeout(timer);
}
let inverval;
let now = new Date().getTime();
!pre && (pre = now);
interval = now - pre;
pre = now;
console.log(`执行第${count}次,间隔时间:${interval}ms ${str}`);
count++;
}
let timer = setInterval(function cb() {
fn();
}, 100);
打开控制台,查看输出结果,会发现6-10次之间是每100ms执行一次。具体请查看结论二及图片解释。

再来看一下分析图:
