2026年03月27日-Node.js事件循环机制 Node.js事件循环深度解析 Node.js的异步非阻塞I/O模型是其高性能的核心。深入理解事件循环机制,对于编写高性能Node.js应用至关重要。 事件循环阶段 Node.js事件循环分为6个阶段,按顺序循环执行: Timers阶段:执行setTimeout和setInterval的回调 Pending Callbacks阶段:执行延迟到下一个循环的I/O回调 Idle/Prepare阶段:内部使用 Poll阶段:获取新的I/O事件,执行I/O回调(除了timers、close、setImmediate) Check阶段:执行setImmediate的回调 Close Callbacks阶段:执行socket.
Node.js的异步非阻塞I/O模型是其高性能的核心。深入理解事件循环机制,对于编写高性能Node.js应用至关重要。
Node.js事件循环分为6个阶段,按顺序循环执行:
执行顺序示例:
console.log('1. 开始'); setTimeout(() => { console.log('2. setTimeout'); }, 0); setImmediate(() => { console.log('3. setImmediate'); }); console.log('4. 结束'); // 输出顺序:1, 4, 2/3(顺序不确定), 3/2
微任务(Microtask):优先级高于宏任务,在每个阶段后执行
宏任务(Macrotask):按阶段执行
执行优先级:
console.log('开始'); setTimeout(() => console.log('timeout1'), 0); Promise.resolve().then(() => { console.log('promise1'); process.nextTick(() => console.log('nextTick1')); }); process.nextTick(() => { console.log('nextTick2'); Promise.resolve().then(() => console.log('promise2')); }); console.log('结束'); // 输出:开始 -> 结束 -> nextTick2 -> promise1 -> promise2 -> nextTick1 -> timeout1
process.nextTick:
process.nextTick(() => { console.log('nextTick回调'); });
setImmediate:
setImmediate(() => { console.log('setImmediate回调'); });
回调函数:
const fs = require('fs'); fs.readFile('file.txt', 'utf8', (err, data) => { if (err) { console.error('读取失败:', err); return; } console.log('文件内容:', data); });
Promise链式调用:
function readFilePromise(filename) { return new Promise((resolve, reject) => { fs.readFile(filename, 'utf8', (err, data) => { if (err) reject(err); else resolve(data); }); }); } readFilePromise('file.txt') .then(data => console.log(data)) .catch(err => console.error(err));
async/await:
const util = require('util'); const readFile = util.promisify(fs.readFile); async function processFile() { try { const data = await readFile('file.txt', 'utf8'); console.log(data); } catch (err) { console.error('错误:', err); } } processFile();
EventEmitter核心模式:
const EventEmitter = require('events'); class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); // 监听事件 myEmitter.on('event', (a, b) => { console.log('事件触发', a, b); setImmediate(() => { console.log('异步处理'); }); }); // 触发事件 myEmitter.emit('event', '参数A', '参数B');
一次性监听器:
myEmitter.once('connect', () => { console.log('仅触发一次'); });
错误处理:
myEmitter.on('error', (err) => { console.error('错误发生:', err); }); // 如果没有error监听器,错误会导致进程退出 myEmitter.emit('error', new Error('出错了'));
可读流(Readable):
const fs = require('fs'); const readStream = fs.createReadStream('large_file.txt', { highWaterMark: 1024 * 1024 // 缓冲区大小1MB }); readStream.on('data', (chunk) => { console.log(`读取到 ${chunk.length} 字节`); }); readStream.on('end', () => { console.log('读取完成'); }); readStream.on('error', (err) => { console.error('错误:', err); });
可写流(Writable):
const writeStream = fs.createWriteStream('output.txt'); writeStream.write('第一行\n'); writeStream.write('第二行\n'); writeStream.end();
管道(Pipe):
const readStream = fs.createReadStream('input.txt'); const writeStream = fs.createWriteStream('output.txt'); readStream.pipe(writeStream);
避免阻塞事件循环:
// 错误示例:同步操作阻塞事件循环 const data = fs.readFileSync('large_file.txt'); // 正确示例:异步操作 fs.readFile('large_file.txt', (err, data) => { // 处理数据 });
使用worker_threads处理CPU密集型任务:
const { Worker } = require('worker_threads'); function runWorker(data) { return new Promise((resolve, reject) => { const worker = new Worker('./heavy-task.js', { workerData: data }); worker.on('message', resolve); worker.on('error', reject); worker.on('exit', (code) => { if (code !== 0) reject(new Error(`Worker stopped with exit code ${code}`)); }); }); }
集群模式利用多核:
const cluster = require('cluster'); const os = require('os'); if (cluster.isMaster) { const cpuCount = os.cpus().length; for (let i = 0; i < cpuCount; i++) { cluster.fork(); } cluster.on('exit', (worker) => { console.log(`Worker ${worker.id} died`); cluster.fork(); // 重启worker }); } else { require('./app.js'); // 启动应用 }
常见原因:
使用heapdump快照:
const heapdump = require('heapdump'); // 手动生成快照 heapdump.writeSnapshot('/tmp/heapdump-' + Date.now() + '.heapsnapshot'); // 定期生成快照用于分析 setInterval(() => { heapdump.writeSnapshot('./snapshots/heap-' + Date.now() + '.heapsnapshot'); }, 60000); // 每分钟
使用v8-profiler监控:
const v8Profiler = require('v8-profiler-next'); v8Profiler.startProfiling('CPU profile'); // ... 运行一段时间 const profile = v8Profiler.stopProfiling('CPU profile'); profile.export((err, result) => { fs.writeFileSync('profile.cpuprofile', result); profile.delete(); });
Node.js事件循环机制是实现高性能异步编程的基础。理解其工作原理,合理使用异步API,避免阻塞操作,才能充分发挥Node.js的并发处理能力。结合性能监控工具,持续优化应用性能,构建高效稳定的Node.js应用。