js EventLoop 事件循环、微任务、宏任务

作者: tww844475003 分类: 前端开发 发布时间: 2021-07-06 20:59

EventLoop 事件循环

主线程循环:即主线程会不停的从执行栈中读取事件,会执行完所有栈中的同步代码。

当遇到一个异步事件后,并不会一直等待异步事件返回结果,而是会将这个事件挂在与执行栈不同的队列中,我们称之为任务队列(Task Queue)。

当主线程将执行栈中所有的代码执行完之后,主线程将会去查看任务队列是否有任务。如果有,那么主线程会依次执行那些任务队列中的回调函数。

宏任务

#浏览器Node
setTimeout
setInterval
setImmediatex
requestAnimationFramex

微任务

#浏览器Node
process.nextTickx
MutationObserverx
Promise.then catch finally

.宏任务(macrotask )和微任务(microtask )

macrotask 和 microtask 表示异步任务的两种分类。

在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首先在 macrotask 的队列(这个队列也被叫做 task queue)中取出第一个任务,执行完毕后取出 microtask 队列中的所有任务顺序执行;之后再取 macrotask 任务,周而复始,直至两个队列的任务都取完。

宏任务和微任务之间的关系

下面来看一个简单示例

setTimeout(() => {
  //执行后 回调一个宏事件
  console.log('内层宏事件3')
}, 0)

console.log('外层宏事件1');

new Promise((resolve) => {
  console.log('外层宏事件2');
  resolve()
}).then(() => {
  console.log('微事件1');
}).then(() => {
  console.log('微事件2')
})

如果能看懂这个复杂的示例,那就可以说对 JS 事件循环理解了

//主线程直接执行
console.log('1');
//丢到宏事件队列中
setTimeout(function () {
  console.log('2');
  process.nextTick(function () {
    console.log('3');
  })
  new Promise(function (resolve) {
    console.log('4');
    resolve();
  }).then(function () {
    console.log('5')
  })
})
//微事件1
process.nextTick(function () {
  console.log('6');
})
//主线程直接执行
new Promise(function (resolve) {
  console.log('7');
  resolve();
}).then(function () {
  //微事件2
  console.log('8')
})
//丢到宏事件队列中
setTimeout(function () {
  console.log('9');
  process.nextTick(function () {
    console.log('10');
  })
  new Promise(function (resolve) {
    console.log('11');
    resolve();
  }).then(function () {
    console.log('12')
  })
})

• 首先浏览器执行js进入第一个宏任务进入主线程, 直接打印console.log(‘1’)

• 遇到 setTimeout  分发到宏任务Event Queue中

• 遇到 process.nextTick 丢到微任务Event Queue中

• 遇到 Promise, new Promise 直接执行 输出 console.log(‘7’);

• 执行then 被分发到微任务Event Queue中

•第一轮宏任务执行结束,开始执行微任务 打印 6,8

•第一轮微任务执行完毕,执行第二轮宏事件,执行setTimeout

•先执行主线程宏任务,在执行微任务,打印’2,4,3,5′

•在执行第二个setTimeout,同理打印 ‘9,11,10,12’

•整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12。

前端开发那点事
微信公众号搜索“前端开发那点事”

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注