美文网首页
12.事件循环-微任务与宏任务

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

作者: 原来哥哥是万家灯火 | 来源:发表于2020-07-03 12:57 被阅读0次

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

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

    • 宏任务(macrotasks): script(整体代码),setTimeout, setInterval, setImmediate, I/O, UI rendering 等对应的回调
    • 微任务(microtasks): process.nextTick, Promises, Object.observe(废弃), MutationObserver 等对应的回调

    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)入栈...

    相关文章

      网友评论

          本文标题:12.事件循环-微任务与宏任务

          本文链接:https://www.haomeiwen.com/subject/ujksqktx.html