宏任务和微任务

  前端小伙伴面试的时候,一定遇到过promise和计时器 输出值、执行先后顺序的题目。下面给大家梳理下具体知识点。

宏任务和微任务

  宏任务包括:

script(整体代码)
setTimeout
setInterval
I/O
UI交互事件
postMessage
MessageChannel
setImmediate(Node.js 环境)

  微任务包括:

Promise.then
Object.observe
MutaionObserver
process.nextTick(Node.js 环境)

执行顺序

  

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

示例分析(我看了好多宏任务微任务的技术帖,示例1几乎都有)

  示例1

  setTimeout(function(){
    console.log('1');
  });
  new Promise(function(resolve){
    console.log('2');
    resolve();
  }).then(function(){
    console.log('3');
  });
  console.log('4');

 

  1. 遇到setTimout,异步宏任务,放入宏任务队列中;
  2. 遇到new Promise,new Promise在实例化的过程中所执行的代码都是同步进行的,所以输出2;
  3. 而Promise.then中注册的回调才是异步执行的,将其放入微任务队列中
  4. 遇到同步任务console.log(‘4’);输出4;主线程中同步任务执行完
  5. 从微任务队列中取出任务到主线程中,输出3,微任务队列为空
  6. 从宏任务队列中取出任务到主线程中,输出1,宏任务队列为空,结束

  

//主线程直接执行
console.log('1');
//丢到宏事件队列中
setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
//微事件1
process.nextTick(function() {
    console.log('6');
})
//主线程直接执行
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    //微事件2
    console.log('8')
})
//丢到宏事件队列中
setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})

  

  1.  首先浏览器执行js进入第一个宏任务进入主线程, 直接打印console.log('1')
  2.  遇到 setTimeout  分发到宏任务Event Queue中
  3.  遇到 process.nextTick 丢到微任务Event Queue中
  4.  遇到 Promise, new Promise 直接执行 输出 console.log('7');
  5.  执行then 被分发到微任务Event Queue中
  6.  第一轮宏任务执行结束,开始执行微任务 打印 6,8
  7.  第一轮微任务执行完毕,执行第二轮宏事件,执行setTimeout
  8.  先执行主线程宏任务,在执行微任务,打印'2,4,3,5'
  9.  在执行第二个setTimeout,同理打印 ‘9,11,10,12’
  10.  整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12。

  以上是自己综合总结大佬们技术帖糅合成的文章,谢谢查看。

 

posted @ 2021-04-27 15:34  底层951  阅读(175)  评论(0)    收藏  举报