浏览器事件循环原理是浏览器实现异步编程模型的核心机制。事件循环允许浏览器能够同时处理多个任务,尽管JavaScript本身是单线程执行的。以下是一个简化的事件循环工作原理的例子:
运行此代码后的事件循环过程如下:
1. 当浏览器解析这段JS代码时,首先执行同步代码:
- '1. 同步代码开始'
- 创建一个setTimeout宏任务,设置其回调函数
- 创建一个Promise,并在其内部立即执行同步代码块,打印'2. 同步代码块内的微任务'
- 注册一个微任务(Promise.then() 的回调)
- '5. 同步代码结束'
2. 主线程执行栈清空后,检查微任务队列(Job Queue),并将其中的所有微任务执行完毕:
- 执行微任务'4. 微任务'
3. 微任务队列为空后,检查是否到了需要执行宏任务(如setTimeout、setInterval、I/O回调等)的时间点:
- 由于setTimeout的延时时间为0,虽然它已经注册,但在实际应用中,至少要等到本次事件循环的微任务队列执行完毕后才会执行(实际延时通常大于0,这里是理想化表述)。
4. 进入下一个事件循环迭代:
- 如果存在待执行的宏任务(如本次setTimeout回调函数),将其移出宏任务队列(Task Queue)并放入主线程执行栈中执行:
- '3. 宏任务'
5. 一旦宏任务执行完毕,主线程再次空闲,继续检查微任务队列,若有微任务则继续执行,否则继续等待新的宏任务到来,如此循环往复。
总结:
事件循环的工作流程就是:
- 执行全局脚本中的同步代码。
- 清理并执行微任务队列中的所有微任务。
- 执行宏任务队列中的下一个宏任务。
- 重复以上步骤。