js循环机制中,for循环阻塞代码时,settimeout执行时机

setTimeout(() => {
    console.log(1);
}, 20);
 
console.log(2);
 
setTimeout(() => {
    console.log(3);
}, 10);
//setTimeout(() => {

  //  console.log(3);
//}, 70); 如果把这个时间改成70,这个执行顺序可能会不变,可能会到最后一个。因为for循环用时是66-71ms不定,所i有执行时机也就 不确定
//以这个setTimout为例,在for循环结束阻塞之后,并运行完所有同步代码之后,就开始找异步进行处理了
//这个10ms的setTimout代码,从加到异步消息队列到被真正执行上,用时,70ms左右
 
console.log(4);
console.time("AA");
 
for(let i = 0; i < 90000000; i++){
    //do somthing这里为了代码阻塞
}
 
console.timeEnd('AA');  //67ms左右不固定
 
console.log(5);
 
setTimeout(() => {
    console.log(6);
}, 8);
 
console.log(7);
 
setTimeout(() => {
    console.log(8);
}, 15);
 
console.log(9);
 
//结果输出:
// 2 4 时间长 5 7 9 3 1 6 8
//在代码从上到下执行时优先执行console.log/time/timeEnd,然后将setTimeout添加到宏任务列队中,在for循环阻塞前先加了两个setTimeout,阻塞后又加了2个。所以在主栈代码执行完成后开始执行列队中的任务,因为阻塞前的先添加进去的所以优先按顺序执行,然后再执行阻塞后的即后添加到列队中的。
console.time("AA");
console.timeEnd("AA");   
相当于一个时间戳记录下中间代码运行时常
总结(我个人总结出的一个规律,不知道对不对)

在for循环会造成阻塞的情况下:

  • 写在for循环前边的setTimout事件的延迟时间要是小于for循环阻塞时间,那么就必然优先于for循环后边的setTimout先执行,(我的理解是比如for循环用时70ms,forq前边的setTimout延迟时间是30ms,那么我们在一开始预编译过程,看到setTimeout就会把它加到消息队列,然后30ms到了就把他加到任务队列,等待被调用。而在30ms时,for阻塞还没有走完,即使for后有延迟为0的定时器,这个0的定时器也要等这这些小于for阻塞时间的定时器回调执行完)
  • 写在for循环前边的setTimout事件的延迟时间要是大于for循环阻塞时间,那么其实 这个for循环真正的延迟时间应该是(比如for循环用时70ms,for前边的setTimout延迟时间是80ms,for循环结束后,大约还有(80-70 = 10ms)的时间才会被加到执行队列,此时就可以用这个10ms去和for下边的其他的setTimout延迟时间比较了,就按照惯例执行 )
  • 写在for循环前边的setTimout事件的延迟时间要是和for循环阻塞时间,大于或是小于在一个很小的范围值内(这个值我没有测),那么输出顺序是会变化的

欢迎大佬指正不对的地方!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值