Node.js 事件循环(Event Loop) 的作用是 管理和调度异步操作,使得 JavaScript 在单线程环境下可以高效地执行 I/O 操作,如文件读写、网络请求、数据库查询等。
主要作用:
-
非阻塞 I/O 处理
- 让 Node.js 在不阻塞主线程的情况下处理多个 I/O 任务。
-
调度异步回调
- 处理
setTimeout()、setImmediate()、process.nextTick()等异步回调函数。
- 处理
-
保持程序运行
- 事件循环不断检查是否有未完成的任务,确保程序不会提前退出。
它具体执行分为6个阶段也是六个队列,和浏览器不一样了,浏览器最多两个队列(宏队列、微队列)
在 Node.js 中,任务可以分为 宏任务(macrotask) 和 微任务(microtask) 。它们在事件循环中的执行顺序有所不同:
1. 宏任务(Macrotask)
宏任务是事件循环的主要任务队列,每次事件循环迭代(tick)时,取出一个宏任务执行,然后检查微任务队列。
常见的宏任务:
setTimeoutsetIntervalsetImmediateI/O 回调(如fs.readFile)MessageChannelclose事件(如stream.on('close', callback))
2. 微任务(Microtask)
微任务比宏任务优先级更高,每次执行完一个宏任务后,会立即执行所有微任务,确保它们在进入下一个宏任务之前执行完毕。
常见的微任务:
process.nextTick(Node.js 特有,优先级最高)Promise.then / catch / finallyqueueMicrotask(比nextTick优先级低,但和 Promise 一样)MutationObserver(浏览器专用,在 Node.js 中不常用)
3. Node.js 事件循环的执行顺序
当事件循环运行时,每一轮执行顺序如下:
- 执行所有同步代码
- 执行所有
process.nextTick() - 执行所有微任务(Promise, queueMicrotask)
- 执行一个宏任务(从队列中取出一个并执行)
- 重复 2-4,直到任务队列清空
如图所示: 这个循环就是一个圈,不是顺序依次执行完一次就行了。 明白这一点很重要!