EventLoop

EventLoop(事件循环)

宏任务和微任务不代表同步和异步!!!!!

关于事件循环的执行过程

微任务包括 process.nextTickpromiseMutationObserver

宏任务包括 scriptsetTimeoutsetIntervalsetImmediateI/OUI rendering

console.log('script start')

async function async1() {
  await async2()
  console.log('async1 end')
}
async function async2() {
  console.log('async2 end')
}
async1()

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

new Promise(resolve => {
  console.log('Promise')
  resolve()
})
  .then(function() {
    console.log('promise1')
  })
  .then(function() {
    console.log('promise2')
  })

console.log('script end')
// script start => async2 end => Promise => script end => async1 end => promise1 => promise2 => setTimeout

想要理解这段代码首先要知道这几点:

1、Promise是异步的,是指他的then()和catch()方法,Promise本身还是同步的

2、在异步函数async/await中真正起作用的是await,async只是一个关键字,不包含await的异步函数其实跟普通函数没什么区别

接下来分析上面代码执行的过程:

首先会先执行script同步代码他是宏任务输出script start,之后执行到async1()会调用async2()(调用async2()是同步的只是当返回的结果promise遇到await之后才算是异步的)输出async2 end,之后返回的promise遇到了await开始让出总线进入微任务队列,开始执行async1()之后的同步代码。接下来会碰到setTimeout他是异步任务(也是宏任务)所以不执行需要将它放入任务队列里面等待,之后会执行new promise()(同步任务)会输出promise,继续向下走会来到resolve()他是异步操作所以需要将它放入微任务队列,继续执行之后的同步代码输出script end当结束完所有同步任务之后开始执行微任务队列里的任务,会首先执行await的任务输出async1 end结束之后,执行微任务队列里的下一项就是promise的resolve()调用的then()输出promise1和promise2,此时微任务队列也执行完了,开始执行宏任务中的异步代码,所以此时去任务队列中查找未完成的宏任务settimeout输出setTimeout

所以 Event Loop 执行顺序如下所示:

  • 首先执行同步代码,这属于宏任务
  • 当执行完所有同步代码后,执行栈为空,查询是否有异步代码需要执行
  • 执行所有微任务
  • 当执行完所有微任务后,如有必要会渲染页面
  • 然后开始下一轮 Event Loop,执行宏任务中的异步代码,也就是 setTimeout 中的回调函数
posted @ 2021-09-30 00:05  律动之心  阅读(37)  评论(0)    收藏  举报