Node.js 事件循环与异步编程深度解析
本文由一缘原创整理,系统梳理 Node.js 事件循环的原理、阶段、异步机制与实战技巧,适合所有 Node.js/后端开发者。
Node.js 事件循环与异步编程深度解析
事件循环是 Node.js 高并发、非阻塞 I/O 的核心。
1. 事件循环的六大阶段
- timers(定时器):setTimeout/setInterval 回调
- pending callbacks:部分系统操作的回调
- idle, prepare:仅内部使用
- poll:I/O 轮询、回调
- check:setImmediate 回调
- close callbacks:如 socket.on(‘close’)
2. 宏任务与微任务
- 宏任务:setTimeout、setInterval、setImmediate、I/O
- 微任务:process.nextTick、Promise.then/catch/finally
- 每个阶段结束后会清空微任务队列
3. 事件循环执行顺序
setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));
process.nextTick(() => console.log('nextTick'));
Promise.resolve().then(() => console.log('promise'));
输出(常见顺序):
nextTick
promise
timeout
immediate
4. process.nextTick 与 Promise 微任务区别
- nextTick 优先级高于 Promise
Promise.resolve().then(() => console.log('promise'));
process.nextTick(() => console.log('nextTick'));
输出:
nextTick
promise
5. I/O、定时器与 setImmediate 的先后
const fs = require('fs');
fs.readFile(__filename, () => {
setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));
});
输出(大多数情况下):
immediate
timeout
6. 异步 I/O 与高并发
- Node.js 单线程事件循环,I/O 操作交给线程池或内核
- 非阻塞 I/O 支持高并发
const fs = require('fs');
for (let i = 0; i < 3; i++) {
fs.readFile(__filename, () => {
console.log('read', i);
});
}
console.log('main');
输出:
main
read 0
read 1
read 2
7. 实战:实现 sleep 函数
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
(async () => {
console.log('start');
await sleep(500);
console.log('end');
})();
输出:
start
(0.5秒后) end
8. 事件循环调试与最佳实践
- 用
node --trace-events
、console.time
、console.log
调试 - 避免阻塞主线程(如大循环、同步 I/O)
- 善用异步 API、Promise、async/await
结语
事件循环是 Node.js 的灵魂,理解它能让你写出高性能、可扩展的后端应用。欢迎留言交流更多 Node.js 深度问题!