Event Loop(浏览器和Node合集)

缘起


最近看到好多人遇到event loop问题,下面小编来给大家弄个完全版本,这篇全是干货,心脏不好,3年以下开发量力阅读!

浏览器题目


没时间解释了,上代码,简单代码没意思,直接上难的,各位看官大大,默写出你认为可以的答案,节奏,我们看答案了!

console.log('1');
new Promise(function(resolve) {
  console.log('10');
  resolve();
}).then(function() {
  console.log('11');
});

async function async1() {
    console.log('2');
    await async2();
    console.log('3');
}
async function async2() {
    console.log('4');
}

async1();

setTimeout(function() {
    console.log('6');
    new Promise(function(resolve) {
        console.log('8');
        resolve();
    }).then(function() {
        setTimeout(() => {
            console.log('13')
            new Promise(function(resolve) {
              console.log('17');
              resolve();
            }).then(function() {
              console.log('16');
            });
        })
        console.log('9')
    }).then(() => {
        setTimeout(() => {
            console.log('14')
        })
        console.log('15')
     })
})

console.log('12');

我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线

答案公布啦

1
10
2
4
12
11
3
6
8
9
15
13
17
16
14

下面听小编解释

  • 第一轮,宏任务,1,10,2,4,12
    微任务,11,3
  • 第二轮,宏任务(定时器里),6,8
    微任务(定时器里面两个then),9,15
  • 第三轮,宏任务(then中的第一个定时器),13,17
    微任务(第三轮宏任务中的定时器中的then)16
  • 第四轮,宏任务(第二个then中的定时器)14

看第二题

console.log('1');
new Promise(function(resolve) {
  console.log('10');
  resolve();
}).then(function() {
  console.log('11');
});

async function async1() {
    console.log('2');
    await async2();
    console.log('3');
}
async function async2() {
   new Promise(function(resolve) {
  console.log('15');
  resolve();
}).then(function() {
  console.log('16');
});

}

async1();

setTimeout(function() {
    console.log('6');
    new Promise(function(resolve) {
        console.log('8');
        resolve();
    }).then(function() {
        console.log('9')
    })
})

console.log('12');

还是老样子,先思考答案再看。

我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线

答案公布啦

1
10
2
15
12
11
16
3
6
8
9

还是老样子,听小编分析一波

  • 第一轮, 宏任务,1,10,2,15,12
    微任务,11,16,3
  • 第二轮,宏任务,6,8
    微任务 9

浏览器总结


以下总结堪称经典版,大家按照这个思路来,能解决所有浏览器上的这类问题。

  • 浏览器一轮下来,先执行一个宏任务,以及处理这轮宏任务产生的所有微任务
  • 同一层级宏任务和微任务(不分层级)的顺序是先进先出
  • await 后面的是宏任务,下面一行是微任务,这也是为何第二题顺序是11,16, 3
  • setTimeout这类定时器,单独组成一个个宏任务,不分层级,按照先后顺序执行
  • 宏任务产生一个微任务,如果微任务产生宏任务(不是定时器类型,是promise类型),那么这个新产生的宏任务执行优先度高于外面的宏任务

最终的题目


熟练记忆上文,我们来做个超级难度的题目吧。哈哈哈,其实不难啦,只是小编加了点难度。

console.log('1');
new Promise(function(resolve) {
  console.log('10');
  resolve();
}).then(function() {
  console.log('11');
});

async function async1() {
    console.log('2');
    await async2();
    console.log('3');
    await async3();
console.log(25)
}
async function async2() {
   new Promise(function(resolve) {
  console.log('21');
  resolve();
}).then(function() {
  console.log('22');
});

}
async function async3() {
   new Promise(function(resolve) {
  console.log('23');
  resolve();
}).then(function() {
  console.log('24');
});

}

async1();

setTimeout(function() {
    console.log('6');
    new Promise(function(resolve) {
        console.log('8');
        resolve();
    }).then(function() {
        setTimeout(() => {
            console.log('13')
            new Promise(function(resolve) {
              console.log('17');
              resolve();
            }).then(function() {
              console.log('16');
            });
        })
        console.log('9')
    }).then(() => {
        setTimeout(() => {
            console.log('14')
 new Promise(function(resolve) {
              console.log('18');
              resolve();
            }).then(function() {
              console.log('19');
            });
        })
        console.log('15')
     })
})

console.log('12');

还是老样子,先思考答案再看。

我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线
我是华丽的分割线

答案公布啦

1
10
2
21
12
11
22
3
23
24
25
6
8
9
15
13
17
16
14
18
19

按照上面的逻辑分析

  • 第一轮, 宏任务1,10,2,21,12
    微任务11,22,3,微任务又产生了async3这个宏任务,会优于外面的定时器这个宏任务执行
  • 第二轮,宏任务async3,23
    微任务24,25(如果继续产生宏任务,会优先执行它产生的宏任务)
  • 第三轮,宏任务(最外面的定时器,第一轮推入宏任务等待队列的)6,8
    微任务(两个then)9,15,同时按照顺序,再次推入两个定时器到宏任务队列
  • 第四轮,宏任务(第一个then的定时器)13,17
    微任务16
  • 第五轮,宏任务(第二个then的定时器)14,18
    微任务19

留个作业


这题如果做出来了,证明能出师了,哈哈哈

console.log('1');
new Promise(function(resolve) {
  console.log('10');
  resolve();
}).then(function() {
  console.log('11');
});

async function async1() {
    console.log('2');
    await async2();
    console.log('3');
    await async3();
console.log(25)
}
async function async2() {
   new Promise(function(resolve) {
  console.log('21');
  resolve();
}).then(function() {
  setTimeout(() => {
            console.log('26')
            new Promise(function(resolve) {
              console.log('27');
              resolve();
            }).then(function() {
              console.log('28');
            });
        })
});

}
async function async3() {
   new Promise(function(resolve) {
  console.log('23');
  resolve();
}).then(function() {
  console.log('24');
    new Promise(function(resolve) {
      console.log('29');
      resolve();
      
    }).then(function() {
      console.log('30');
    });
});

}

setTimeout(() => {
    new Promise(function(resolve) {
        console.log('33');
        resolve();
    }).then(function() {
        new Promise(function(resolve) {
      console.log('35');
      resolve();
        setTimeout(() => {
            console.log(37)
        })
    }).then(function() {
      console.log('36');
        new Promise(function(resolve) {
              console.log('38');
                setTimeout(() => {
                    console.log(40)
                })
              resolve();
            }).then(function() {
              
              console.log('39');
            });
    });
    })
})

async1();

setTimeout(function() {
    console.log('6');
    new Promise(function(resolve) {
        console.log('8');
        resolve();
    }).then(function() {
        setTimeout(() => {
            console.log('13')
            new Promise(function(resolve) {
              console.log('17');
              resolve();
            }).then(function() {
              console.log('16');
            });
        })
        console.log('9')
    }).then(() => {
        setTimeout(() => {
            console.log('14')
 new Promise(function(resolve) {
              console.log('18');
              resolve();
            }).then(function() {
              console.log('19');
            });
        })
        console.log('15')
     })
})

let a = setInterval(() => {
clearTimeout(a)
    console.log(32)
})

setTimeout(() => {
    console.log(31)
})

console.log('12');

node与浏览器的不同之处


来个简单版本的总结,下次写文章时,来个全面的分析,哈哈哈!

  • node的宏任务和微任务都是有顺序的,下面给个大致的顺序
  • node中的宏任务,I/O>setImmediate>setTimeout
  • node中微任务,process.nextTick>promise.then>await后面的

尾声


美好的时间总是短暂的,各位同学看了小编的文章,是不是功力大涨,一统武林指日可待,哈哈哈。
如果喜欢小编,记得点赞,多多关注啊!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值