12.事件循环-微任务与宏任务

2020-07-03  本文已影响0人  原来哥哥是万家灯火

事件循环机制
js中的代码,其上下文进入执行栈之后,引擎会判断是不是异步操作(如DOM事件、timer、异步请求)。如果是异步任务,浏览器会将其上下文移出执行栈,交给浏览器的其他模块(如chrome的webcore模块)去处理。等到其达到触发条件后,再将其对应的回调函数添加到 任务队列 (task queue)中去。等执行栈中的任务清空后,引擎会将任务队列中的回调函数重新压入执行栈。

微任务与宏任务
执行栈清空完毕后,引擎会将任务队列中的任务(回调函数)重新压入执行栈。这些任务分为宏任务(macrotasks)和微任务(microtasks)

Promise/A+的规范中,Promise的实现可以是微任务,也可以是宏任务。但是大多数原生实现的Promise都是微任务。比如chrome、node。但一些polyfill中实现的Promise,其实就是宏任务。

每次事件循环,是先执行一个宏任务、然后执行所有的微任务。因为script(整体代码)也是一个宏任务,所以执行栈清空后,先取的任务是所有微任务。这是符合先宏任务、然后所有微任务的。

例:

let p = new Promise(function (resolve) {
    console.log(1)
    resolve()
})

p.then(function () {
    console.log(2)
}).then(function () {
    console.log(3)
    Promise.resolve().then(function() {
        console.log(4)
   })
})

setTimeout(function () {
    console.log(5)
},0)

其过程为:
log(1)入栈,执行完毕
第一个then、第二个then入栈,其回调被添加到微任务队列
settimeout入栈,其回调被添加到宏任务队列
执行栈清空,第一个微任务入栈并执行完毕(整体代码也相当于一个宏任务,所以开始所有微任务)
第二个微任务入栈,又插入了一个新的微任务log(4) ,第二个执行完毕
微任务log(4)入栈并执行完毕,此时所有微任务被清空
开始下一轮循环
宏任务log(5)入栈...

上一篇下一篇

猜你喜欢

热点阅读