js运行机制之微任务和宏任务

  • 宏任务队列可以有多个,微任务队列只有一个;
  • 主线程上的任务是第一个宏任务;
  • 会建立宏任务的有:setTimeOut、 setInterval、 requestAnimationFrame
  • 会建立微任务的有:Promise的回调、 process.nextTick
  • 当有一个宏任务队列执行完毕后,会执行微任务队列中的全部内容,然后执行另一个宏任务队列,如此反复

js代码执行机制基本是这样的:当遇到3中的内容时建立新的宏任务,遇到4中的内容时将其加入微任务,然后按5中的顺序执行。结合下面的例子来分析一下:

复制代码
console.log("1")


// setTimeOut函数不设置时间
setTimeout ( () => {
    console.log('2')
    new Promise( (resolve => {
        console.log("3")
        resolve()
    })) .then ( () => console.log("4"))
})


new Promise ( (resolve, reject) => {
    console.log("5")
    resolve()
}) .then( () => console.log('6'))


setTimeout ( () => {
    console.log('7')
})


console.log("8")
复制代码

*测试发现setTimeOut不加时间与设置时间为0效果相同,都是等主线程上的代码执行完后立即执行

分析:

js代码从上到下执行,先遇到console.log(1),将其加入主线程的宏任务队列,然后发现setTimeOut,为其创建第二个宏任务队列并将其加入,其中代码先不执行,然后遇到Promise,将其中的console.log(5)加入主线程的宏任务队列,将then回调函数中的内容加入微任务队列,继续往下发现第二个setTimeOut,将其放入第三个宏任务队列,最后将console.log(8)放入主线程宏任务队列,到此,代码已经完成了在不同队列中的分布,详细情况为:

接下来开始执行第一个宏任务队列,分别打印1,5,8,然后执行微任务队列,打印6,微任务队列变为空。接着执行第二个宏任务队列,开始执行第一个setTimeOut中的代码:先后打印 2,3,并将回调函数中的console.log(4)加入微任务。此时第二个宏任务队列执行完毕,开始执行微任务队列,打印 4。接着执行第三个宏任务队列,打印 7。执行完毕。所以最终输出顺序为:15862347。

原文地址:https://www.cnblogs.com/crazycode2/p/12150548.html