初探事件循环-Event Loop

本文解析了一段JavaScript代码的执行顺序,解释了事件循环机制下,同步代码、Promise和setTimeout如何按特定顺序执行。深入探讨了MicroTask与MacroTask的区别及执行优先级。

  最近面试遇到这样一道面试题:

console.log(1);
setTimeout(()=> {
    console.log(2);
},1000);
setTimeout(() => {
    console.log(3);
},0);
new Promise((resolve, reject) => {
    console.log(4);
    resolve();
}).then(() => {
    console.log(5);
}).then(() => {
    console.log(6)
})
console.log(7);
new Promise((resolve, reject) => {
    console.log(8);
    resolve();
}).then(() => {
    console.log(9);
}).then(() => {
    console.log(10)
})

问:上述代码的输出结果是啥?
答:1、4、7、8、5、9、6、10、3、2

  为什么输出结果是上边这样的顺序呢?promise的then回调函数会在setTimeout(function () {}, 0);之前输出呢?我们可以先从事件循环说起:
  Javascript是单线程的,在执行时,会先执行同步代码,遇到异步执行的代码,会先将代码放入到任务队列中,主线程的代码执行完毕,就会从任务队列中取出任务执行。 按照当前描述,Javascript会先执行同步代码,即console.log()函数和promise实例对象;然后,将其余的异步函数加入到任务队列中。
  接下来,promise的then回调和setTimeout函数,都是异步执行,那么为什么promise的then回调会在setTimeout之前输出呢?原因如下:
  在JavaScript中,任务队列不止有一个,包含:MacroTask和MicroTask,在Javascript中可以包含多个MacroTask,但是只能包含一个MicroTask,在代码执行中,异步事件会根据自己的类型加入到不同的任务队列中。
  Javascript开始执行事件时,会先清空函数调用栈,然后先执行MicroTask任务,再执行MacroTask;在执行这两个任务队列时,会先将MicroTask任务队列清空,然后再去执行MacroTask队列中的一个。然后循环执行…

MicroTask: Promise、Object.observe
MacroTask: setTimeout、setInterval、setImmediate、UI渲染

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值