胖蔡说技术
随便扯扯

JavaScript 之宏任务与微任务

JavaScript是单线程的,JavaScript将运行任务分为同步任务与异步任务,同步任务由JavaScript主线程依次执行,异步任务委托给宿主环境执行,对于已完成的异步任务对应的回调函数,会被加入任务队列中等待执行。然后任务队列依次执行任务。

本文所说的宏任务和微任务说的都是上述的异步任务,它们都在任务队列中,但不同属于一个任务队列。如下图所示,列出了常见的宏任务和微任务的类型:

宏任务

宏任务(macro-task )是指任务队列中等待主线程执行的代码块,可以理解为每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。常见的如:

  • setTimeout
  • setInterval
  • setImmediate(Node.js 环境)
  • UI rending/UI事件
  • I/O
  • 主线程同步script代码
  • xhr
  • requestAnimationFrame(仅浏览器)
  • MessageChannel

常见代码如下:

setTimeout(() => {
    console.log('ha ha ha');
}, 0);

// 执行结果
ha ha ha 

微任务

微任务(micro-task)是指任务队列中将当前宏任务执行完后,页面渲染之前需要执行的任务,常见的微任务代码块如:

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

示例代码如下:

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

// 执行结果
1
4
2
3

交替执行

如下通过一个示例来看下宏任务、微任务交替执行的执行结果:

//主线程直接执行
console.log('1');//主线程任务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');//微任务1
})
//主线程直接执行
new Promise(function(resolve) {
    console.log('7');//主线程任务2
    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
7
6
8
2
4
3
5
9
11
10
12
赞(0) 打赏
转载请附上原文出处链接:胖蔡说技术 » JavaScript 之宏任务与微任务
分享到: 更多 (0)

请小编喝杯咖啡~

支付宝扫一扫打赏

微信扫一扫打赏