如何理解 JavaScript 中的事件循环
如何理解 JavaScript 中的事件循环(Event Loop)
JavaScript 是一种单线程语言,它通过事件循环(Event Loop)机制来实现异步操作的调度与执行。理解事件循环有助于我们更好地编写异步代码,避免一些常见的“回调陷阱”或异步顺序错误。
1. 什么是事件循环?
事件循环是一种协调机制,用于决定哪些代码在何时执行,特别是在处理异步任务(如定时器、网络请求、Promise 等)时。事件循环的核心流程包括:
- 执行同步代码(同步任务进入调用栈)
- 执行所有微任务(Microtasks)
- 从宏任务队列中取出下一个宏任务执行
- 重复上述过程
2. 同步任务 vs 异步任务
- 同步任务:立即执行,按顺序排列在调用栈中。
- 异步任务:交由浏览器或 Node 的 Web API 执行,完成后加入任务队列中等待执行。
3. 微任务与宏任务
类型 | 举例 | 特点 |
---|---|---|
微任务 Microtask | Promise.then、MutationObserver、queueMicrotask | 在当前宏任务完成后立即执行 |
宏任务 MacroTask | setTimeout、setInterval、I/O、setImmediate | 会排队等待事件循环进入下一个周期 |
4. 执行顺序示例
1 |
|
输出结果:
1 |
|
原因分析:
console.log('1')
和console.log('4')
是同步任务,先执行。setTimeout
是宏任务,进入任务队列。Promise.then
是微任务,在当前宏任务执行完后立即执行。- 所以先输出 3,然后才是
setTimeout
的 2。
5. setTimeout(fn, 0) 并不是“立即执行”
即便设置为 0 毫秒,setTimeout 回调也不会在当前调用栈执行完前运行,因为它是宏任务,会等到所有当前宏任务和微任务完成后才进入执行。
6. 实战技巧:分批执行避免阻塞
如果你有一个很大的循环操作,不建议一次性执行
1 |
|
可以改为使用 setTimeout 分批执行:
1 |
|
7. 总结
JavaScript
是单线程语言,通过事件循环处理异步任务。微任务优先于宏任务执行。Promise.then
总是在同步任务之后,setTimeout
之后执行。- 理解事件循环,有助于编写更加流畅、性能更佳的前端应用。
如何理解 JavaScript 中的事件循环
http://www.zinete.com/2024/07/12/如何理解 JavaScript 中的事件循环/