JavaScript 事件循环(EventLoop)

事件循环(EventLoop)是 JavaSciprt 引擎中的一个机制,它是一个不断在执行任务和休眠等待任务之间转换的无限循环 —— 有任务就依次执行完毕,再等待新任务,有任务…执行完毕…等待新任务……

在执行 JavaScript 代码的过程中,同步代码会被放入调用栈(Call Stack)中直接执行, 而异步任务会放入对应的异步队列。 异步任务分为 2 种,一种是由浏览器(Web APIS)提供的宏任务,如 setTimeout​, setInterval​ 等,一种是 JavaScript 语法定义的微任务,典型的如 Promise​ 和 fetch​ 等。

上面说过同步代码会直接执行,而当本轮中的同步代码执行完毕之后,会去检查微任务队列,有则依次执行。在此过程中产生的新的微任务也会放入队列,直到本轮微任务全部执行完毕。

接下来会执行浏览器 UI 线程的渲染工作,然后再检查 Web Work 任务,有则执行。

最后,检查宏任务队列,有则执行(又回到了上面的流程)。

如此不断的循环,直到任务队列为空。

可通过这个 latentflip.com/loupe/ 可视化工具,加深理解。

总结一下,可以把 EventLoop 的执行流程描述为:

  1. (最开始整个脚本可以视为一个正在执行的宏任务)
  2. 执行过程中同步代码放入调用栈直接执行,异步任务会放入异步任务队列等待执行
  3. 同步代码执行完毕(当前的宏任务出队)
  4. 检查微任务队列,有则依次执行,直至全部执行完毕
  5. 执行浏览器 UI 线程的渲染工作
  6. 检查是否有 Web Worker​​任务,有则执行
  7. 检查宏任务队列,有则执行,回到 2,依此循环,直到异步任务队列为空

参考链接: