function formatDate(date){ console.log(date.getFullYear()+"-"+(date.getMonth()+1)+date.getDate()+" "+date.getHours()+":"+date.getMinutes()+":"+date.getSeconds()+":"+date.getMilliseconds()); } var timer ; function test(){ timer = setInterval(function(){ console.log('interval'); },8000); var startDate = new Date(); var now = new Date(); for(var i =0; i<5; i++){ formatDate(startDate); // 5 second while(new Date () - startDate < 5*1000){ } startDate = new Date(); } } test();
主逻辑test函数大概执行5×5=25秒,定时器setInterval大概8秒执行一次
那么在主逻辑运行的25秒内,此定时器大概被触发3(25/8=3)次
时刻8秒触发一次s1,
时刻18秒触发一次s2,
时刻24秒触发一次s3,
显然这些时刻,主逻辑test函数还在执行,那么猜想
A.定时器回调函数被放入到任务队列(消息队列)中去,等待主逻辑执行完毕后调用,
那么一旦执行任务队列的调用,将会有s1,s2,s3被相继取出,执行,输出3次interval,基本上可以理解为立刻输出3次interval,毕竟定时器回调函数太简单,基本不耗时
B.定时器智能化,在任务队列里面只保留一个回调任务,时刻8秒,s1放进去,然后时刻16秒,主逻辑还在执行,s1还在等待,那么s2被丢弃,同理,s3被丢弃(还有一种情况,是不是可以说s1丢弃,s2丢弃,s3保留呢?我不晓得)
在chrome下执行,发现按照B猜想执行,只有一个定时器回调被保留
那么继续,假设我们把定时器间隔设定为9秒,那么在主逻辑执行到25秒时间内,有如下调用:
时刻9秒生成回调s1,
时刻18秒生成回调s2(丢弃),
时刻27秒生成回调s3
我们发现,大概在第25秒主逻辑执行完毕,从任务队列里面取出s1执行,然后在第27秒,生成s3放到任务队列,然后JS运行时取出执行,s3-s1之间间隔,大概27-25=2s,
那么明显,定时器不靠谱,不能保证每次执行会间隔起码9秒。。。
同时,试想,如果定时器回调逻辑太复杂,执行也要30秒,甚至更多,会发生什么?