浏览器中的事件循环

浏览器中的事件循环是怎么进行的?

先看以下代码

setTimeout(()=>{
  console.log('s1')
  Promise.resolve().then(()=>{
    console.log('s2')
  })
  Promise.resolve().then(()=>{
    console.log('s3')
  })
})
Promise.resolve().then(()=>{
  console.log('p1')
  setTimeout(()=>{
    console.log('s2')
  })
  setTimeout(()=>{
    console.log('s3')
  })
})

上面的代码执行结果是怎么样的?
具体过程我们进行下面的分析

浏览器中事件分为宏任务和微任务

  • setTimeout被归为宏任务,Promise.then则归为微任务

  • 浏览器对宏任务和微任务的执行顺序是有规则的

    • 优先会将同步任务加入队列,微任务加入微任务队列,宏任务加入宏任务队列
    • 优先清空微任务队列,清空微任务后,执行下一个宏任务
    • 宏任务执行完成后,会再次去清空微任务队列,因为在宏任务中可能存在微任务,会被加入微任务队列
    • 再次清空了微任务队列后,会继续重复执行下一个宏任务然后清空微任务队列,直到所有队列都被清空
  • 上面代码会按照以下步骤进行事件循环

    1. 首先浏览器会按从上到下的顺序执行所有同步代码,把宏任务和微任务分别放到不同的队列中
      上面代码中t1和p1是同步的,t1是宏任务,放到宏任务队列,p1是微任务,放到微任务队列

    1. 浏览器会优先执行微任务队列中的任务,所以p1会优先执行,此时p1被首先输出

    1. p1输出后,在微任务中发现还有两个宏任务s2和s3,这两个任务则被追加到宏任务队列中

    1. 微任务p1执行完成,弹出队列。此时微任务列队中没有任务了,开始执行宏任务队列中的第一个任务s1,此时输出s1,同时发现s1中还有两个微任务p2,p3,这两个任务则被按顺序添加到微任务队列中

    1. 此时s1执行完成,弹出队列,将开始执行微任务队列中的任务

    1. 此时微任务队列中有p2和p3两个任务,按照顺序执行,则会输出p2,p3,同时p2、p3弹出队列

    1. 此时微任务队列被清空,又会执行宏任务队列中的下一个宏任务,即s2,同理,s3与s2一样,两个任务按顺序依次输出s2、s3并弹出队列

    1. 最终结果就是依次输出p1、s1、p2、p3、s2、s3
原文地址:https://www.cnblogs.com/MissSage/p/15063951.html