JavaScript 事件循环(EventLoop)
事件循环(EventLoop)是 JavaSciprt 引擎中的一个机制,它是一个不断在执行任务和休眠等待任务之间转换的无限循环 —— 有任务就依次执行完毕,再等待新任务,有任务…执行完毕…等待新任务……
在执行 JavaScript 代码的过程中,同步代码会被放入调用栈(Call Stack)中直接执行, 而异步任务会放入对应的异步队列。
异步任务分为 2 种,一种是由浏览器(Web APIS)提供的宏任务,如 setTimeout
, setInterval
等,一种是 JavaScript 语法定义的微任务,典型的如 Promise
和 fetch
等。
上面说过同步代码会直接执行,而当本轮中的同步代码执行完毕之后,会去检查微任务队列,有则依次执行。在此过程中产生的新的微任务也会放入队列,直到本轮微任务全部执行完毕。
接下来会执行浏览器 UI 线程的渲染工作,然后再检查 Web Work 任务,有则执行。
最后,检查宏任务队列,有则执行(又回到了上面的流程)。
如此不断的循环,直到任务队列为空。
可通过这个 latentflip.com/loupe/ 可视化工具,加深理解。
总结一下,可以把 EventLoop 的执行流程描述为:
- (最开始整个脚本可以视为一个正在执行的宏任务)
- 执行过程中同步代码放入调用栈直接执行,异步任务会放入异步任务队列等待执行
- 同步代码执行完毕(当前的宏任务出队)
- 检查微任务队列,有则依次执行,直至全部执行完毕
- 执行浏览器 UI 线程的渲染工作
- 检查是否有
Web Worker
任务,有则执行 - 检查宏任务队列,有则执行,回到 2,依此循环,直到异步任务队列为空
参考链接: