浏览器事件循环和我的头发

深入理解Event Loop

        btn.addEventListener("click", event => {
            setTimeout(() => {console.log("S1")}, 0)
            Promise.resolve().then(() => console.log("M1"))
            console.log("L1")
        })
        btn.addEventListener("click", event => {
            setTimeout(() => {console.log("S2")}, 0)
            Promise.resolve().then(() => console.log("M2"))
            console.log("L2")
        })

点击btn
输出:L1、M1、L2、M2、S1、S2
大致过程是这样的:

  1. 从浏览器的事件监听线程出发,看到btn被点击
  2. 将console.log("S1")交给浏览器中的定时器线程
  3. 将console.log("M1")加入微任务队列
  4. 将console.log("L1")加入JS主线程
  5. JS主线程执行任务输出“L1”
  6. 执行执行栈为空,微队列任务加入其中,输出“M1”
  7. 将console.log("S2")交给浏览器中的定时器线程
  8. 将console.log("M2")加入微任务队列
  9. 将console.log("L2")加入JS主线程
  10. JS主线程执行任务输出“L2”
  11. 执行执行栈为空,微队列任务加入其中,输出“M2”
  12. 定时器线程将log("S1")和log("S2")加入宏任务队列
  13. JS执行栈空着所以依次输出”S1“和”S2“

大家都很聪明,应该都理解!

        btn.addEventListener("click", event => {
            setTimeout(() => {console.log("S1")}, 0)
            Promise.resolve().then(() => console.log("M1"))
            console.log("L1")
        })
        btn.addEventListener("click", event => {
            setTimeout(() => {console.log("S2")}, 0)
            Promise.resolve().then(() => console.log("M2"))
            console.log("L2")
        })
        btn.click()

输出:L1、L2、M1、M2、S1、S2

理解了上一个,这个就很好理解了,
js出发click事件所以在点击事件完成之前JS主线程中始终有一个btn.click等待着执行完毕返回结果。
大致过程就是

  1. S1进宏任务队列
  2. M1进微任务队列
  3. 输出L1
  4. S2进宏任务队列
  5. M2进微任务队列
  6. 输出L2
  7. 微任务队列的任务依次加入JS执行栈执行,输出M1,M2
  8. 宏任务队列的任务依次加入执行,输出S1,S2

奇库秀,我的头发又少了。。。

阅读 235

推荐阅读