微任务和宏任务哪个先执行?

先说一下事件循环:

先执行宏任务,再检查有没有微任务,如果有就执行微任务,然后渲染dom,最后进入下一次事件循环。

更官方的解释:先执行同步代码,遇到异步宏任务则将异步宏任务放入宏任务队列中,遇到异步微任务则将异步微任务放入微任务队列中,当所有同步代码执行完毕后,再将异步微任务从队列中调入主线程执行,微任务执行完毕后再将异步宏任务从队列中调入主线程执行,一直循环直至所有任务执行完毕。

为什么有人认为微任务先执行?

     setTimeout(() => {
      console.log("宏任务");
    }, 0);
    Promise.resolve().then((e) => {
      console.log("微任务");
    });

因为上面的代码会先输出微任务,再输出宏任务

这是因为宏任务试下一个时间循环开始的宏任务,而微任务是这次事件循环就执行的微任务,他们之间隔了一个dom渲染,所以造成了微任务比宏任务更快执行的错觉。

举个栗子

例题1

setTimeout(function(){
    console.log('1')
});
new Promise(function(resolve){
    console.log('2');
    resolve();
}).then(function(){
    console.log('3')
});
console.log('4');
new Promise(function(resolve){
    console.log('5');
    resolve();
}).then(function(){
    console.log('6')
});
setTimeout(function(){
    console.log('7')
});
function bar(){
    console.log('8')
    foo()
}
function foo(){
    console.log('9')
}
console.log('10')
bar()

解析

  1. 首先浏览器执行Js代码由上至下顺序,遇到setTimeout,把setTimeout分发到宏任务Event Queue中
  2. new Promise属于主线程任务直接执行打印2
  3. Promis下的then方法属于微任务,把then分到微任务 Event Queue中
  4. console.log(‘4’)属于主线程任务,直接执行打印4
  5. 又遇到new Promise也是直接执行打印5,Promise 下到then分发到微任务Event Queue中
  6. 又遇到setTimouse也是直接分发到宏任务Event Queue中,等待执行
  7. console.log(‘10’)属于主线程任务直接执行
  8. 遇到bar()函数调用,执行构造函数内到代码,打印8,在bar函数中调用foo函数,执行foo函数到中代码,打印9
  9. 主线程中任务执行完后,就要执行分发到微任务Event Queue中代码,实行先进先出,所以依次打印3,6
  10. 微任务Event Queue中代码执行完,就执行宏任务Event Queue中代码,也是先进先出,依次打印1,7。

最终结果:2,4,5,10,8,9,3,6,1,7

例题2

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

执行结果: 5 7 10 8 1 2 4 6 3

宏任务微任务

1.宏任务:当前调用栈中执行的代码成为宏任务。(主代码快,定时器等等)。

2.微任务:当前(此次事件循环中)宏任务执行完,在下一个宏任务开始之前需要执行的任务,可以理解为回调事件。(promise.then,proness.nextTick等等)。

3.宏任务中的事件放在callback queue中,由事件触发线程维护;微任务的事件放在微任务队列中,由js引擎线程维护。

宏任务:  I/O、setTimeout、setInterval、setImmediate、requestAnimationFrame

微任务: promise.then、process.nextTick、object.observe、MutationObserve

注意:new Promise是同步任务

本文部分参考: 

微任务和宏任务哪个先执行 - 怡红公子0526 - 博客园

如果还是不明白,推荐看一下这个试试JS宏任务和微任务_js宏任务与微任务_奔波儿灞...的博客-CSDN博客

  • 8
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值