ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

宏任务和微任务

2022-08-18 17:04:37  阅读:137  来源: 互联网

标签:function resolve console log 任务 Promise


作者:ZH彪
链接:https://www.jianshu.com/p/bcbf7894027c
来源:简书

微任务和宏任务皆为异步任务,它们都属于一个队列,主要区别在于他们的执行顺序,Event Loop的走向和取值。

宏任务和微任务的分配

宏任务                    浏览器          Node
I/O                       ✅            ✅
setTimeout                ✅            ✅
setInterval               ✅            ✅
setImmediate              ❌            ✅
requestAnimationFrame     ✅            ✅ 

         微任务
process.nextTick          ❌            ✅
MutationObserver          ✅            ❌
Promise.then catch finally✅            ✅

 

宏任务与微任务之间的执行顺序(同步任务->微任务->宏任务)
下面说说执行到宏任务后是怎么继续运行的
(这里声明下,整段js代码就是第一个大的宏任务,事件循环是由这第一个宏任务开始的,然后分出微任务,这里是为了理解微任务宏任务的执行区别就先跳过这第一层)

说一个很有名的银行例子:银行柜台前排着一条队伍,都是存钱的人,存钱属于宏任务,这条队伍就是宏任务队列,当一个‘宏大爷’被叫到了自己的号码,就上前去--被处理,处理存钱业务时,‘宏大爷’突然想给自己的存款办个微理财(微任务),那么银行职员就将他的需求添加到自己的微任务队列,大爷就不用再排队了,直接在存钱宏任务进行完后就处理衍生出来的微任务理财,办理财时大爷又说办个信用卡,那就又排到微任务队列里。但要是在此次存钱时‘宏大爷’说他还要存钱,且是他老伴要存钱,也是宏任务,但不好意思,需要取号到宏任务队列的后面排队(这里就是在宏任务进行时产生微任务和宏任务的处理方式)。

 

//宏任务1
    setTimeout(function () {
      console.log('1');//宏任务1
    });

    //Promise
    new Promise(function (resolve) {
      console.log('2');//同步任务1
      resolve();
    }).then(function () {
      console.log('3');//微任务1
    });

    //同步任务
    console.log('4');//同步任务2
    // 一步一步来分析,js可以看成是一个大的宏任务,以上是开始的一段,可以看到按照代码顺序有setTimeout、Promise、Promise.then()、console.log
    // setTimeout 是宏任务 、Promise是微任务、console.log是同步任务,而Promise是将异步的操作用同步的流程表达出来,所以在Promise里面的是同步任务、.then()里面的是微任务
    // 所以按照代码书写顺序和执行顺序 同步任务 > 微任务 > 宏任务,最先执行的是同步任务1,然后是同步任务2、微任务1、宏任务1
    //所以到目前为止打印出来的依次是:2 4 3 1

    //下面是宏任务2和宏任务3,注意宏任务2里面有很多同步任务和微任务,这些都是包括在宏任务2里面的
    //宏任务2
    setTimeout(function () {
      console.log('5');//宏任务2中的同步任务
      new Promise(function (resolve) {
        console.log('6');//宏任务2中的同步任务
        new Promise(function (resolve) {//宏任务2中的微任务
            console.log('x1');
            resolve();
          }).then(function () {
            console.log('X2');
          });
        setTimeout(function () {//宏任务2中的宏任务
          console.log('X3');
          new Promise(function (resolve) {//宏任务2中的宏任务中的同步任务
            console.log('X4');
            resolve();
          }).then(function () {//宏任务2中的宏任务中的微任务
            console.log('X5');
          });
        })
        resolve();
      }).then(function () {//宏任务2中的微任务
        console.log('7');
      });
    })
    //现在代码走到了宏任务2里面,开始按照顺序执行,首先可以看到宏任务2里面有两块,1个是宏任务2中的同步任务(console.log('6');),1个是 Promise
    // console.log('5'); 是同步任务,所以最先打印
    //宏任务2的第一个Promise里面包含的有:同步任务console.log('6')和Promise、微任务Promise.then、宏任务setTimeout
    //同步任务 '6'最先打印,然后是Promise里面的同步任务'x1',微任务Promise.then()里面的'x2'
    //而setTimeout是宏任务,得丢到宏任务列表的最后面去排队(目前的代码最后面排着的是宏任务3,所以这个宏任务得排在宏任务3的后面)
    //最后执行外面的微任务Promise.then() console.log('7');
    //所以这一块的打印顺序为:5 6 x1 x2 7

    //宏任务3
    setTimeout(function () {
      console.log('8');
    });
    // 因为宏任务3里面只有一个同步任务 所以直接输出 8 
    // 接下来执行宏任务2里面的宏任务 也就是刚被丢出来排在最后面的setTimeout,跟宏任务2的执行顺序同理,所以输出顺序为:x3 x4 x5
    //(对于这段代码node环境和浏览器环境输出一致)
    //最终输出答案:2,4,3,1,5,6,x1,x2,7,8,x3,x4,x5

无注解的原代码

setTimeout(function () {//宏任务1
      console.log('1');
    });
    new Promise(function (resolve) {
      console.log('2');//同步任务1
      resolve();
    }).then(function () {//微任务1
      console.log('3');
    });
    console.log('4');//同步任务2
    setTimeout(function () {//宏任务2
      console.log('5');//宏任务2中的同步任务
      new Promise(function (resolve) {
        console.log('6');//宏任务2中的同步任务
        new Promise(function (resolve) {//宏任务2中的微任务
            console.log('x1');
            resolve();
          }).then(function () {
            console.log('X2');
          });
        setTimeout(function () {//宏任务2中的宏任务
          console.log('X3');
          new Promise(function (resolve) {//宏任务2中的宏任务中的同步任务
            console.log('X4');
            resolve();
          }).then(function () {//宏任务2中的宏任务中的微任务
            console.log('X5');
          });
        })
        resolve();
      }).then(function () {//宏任务2中的微任务
        console.log('7');
      });
    })
    setTimeout(function () {//宏任务3
      console.log('8');
    });
    //(对于这段代码node环境和浏览器环境输出一致)
    //输出答案:2,4,3,1,5,6,x1,x2,7,8,x3,x4,x5

 

 

 

标签:function,resolve,console,log,任务,Promise
来源: https://www.cnblogs.com/Luffy-RedRoc/p/16599280.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有