答: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) {
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) {
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执行一次。具体请查看结论二及图片解释。
再来看一下分析图: