Node.js中常见的事件类型
在Node.js中,核心设计理念就是事件驱动,几乎所有异步操作都基于事件机制,常见的事件类型:
1. EventEmitter 基础事件
const EventEmitter = require('events');class MyEmitter extends EventEmitter {}const myEmitter = new MyEmitter();// 绑定自定义事件
myEmitter.on('event', () => {console.log('触发事件');
});myEmitter.on('data', (data) => {console.log('接收到数据:', data);
});// 一次性事件
myEmitter.once('onceEvent', () => {console.log('这个事件只会触发一次');
});// 触发事件
myEmitter.emit('event');
myEmitter.emit('data', { message: 'Hello' });
myEmitter.emit('onceEvent');
myEmitter.emit('onceEvent'); // 这次不会触发
2. 文件系统事件 (fs模块)
const fs = require('fs');// 文件读取事件
const readStream = fs.createReadStream('file.txt');readStream.on('data', (chunk) => {console.log('接收到数据块:', chunk.length, 'bytes');
});readStream.on('end', () => {console.log('文件读取完成');
});readStream.on('error', (err) => {console.error('读取文件时出错:', err);
});readStream.on('open', () => {console.log('文件已打开');
});readStream.on('close', () => {console.log('文件已关闭');
});
3. HTTP服务器事件
const http = require('http');const server = http.createServer();// 服务器事件
server.on('request', (req, res) => {console.log('接收到请求:', req.method, req.url);res.end('Hello World');
});server.on('connection', (socket) => {console.log('新的连接建立');
});server.on('close', () => {console.log('服务器已关闭');
});server.on('error', (err) => {console.error('服务器错误:', err);
});server.listen(3000, () => {console.log('服务器运行在端口 3000');
});
4. HTTP请求/响应事件
const http = require('http');http.createServer((req, res) => {// 请求事件req.on('data', (chunk) => {console.log('接收到请求体数据:', chunk.toString());});req.on('end', () => {console.log('请求数据接收完成');});req.on('error', (err) => {console.error('请求错误:', err);});// 响应事件res.on('close', () => {console.log('响应已关闭');});res.on('finish', () => {console.log('响应已完成');});res.end('Response complete');
}).listen(3000);
5. 流(Stream)事件
const { Readable, Writable, Transform } = require('stream');// 可读流事件
const readableStream = new Readable({read(size) {this.push('Hello ');this.push('World');this.push(null); // 结束流}
});readableStream.on('data', (chunk) => {console.log('读取数据:', chunk.toString());
});readableStream.on('end', () => {console.log('流读取结束');
});readableStream.on('error', (err) => {console.error('流错误:', err);
});// 可写流事件
const writableStream = new Writable({write(chunk, encoding, callback) {console.log('写入数据:', chunk.toString());callback();}
});writableStream.on('finish', () => {console.log('所有数据已写入');
});writableStream.on('pipe', (src) => {console.log('有流管道接入');
});writableStream.on('unpipe', (src) => {console.log('有流管道断开');
});
6. 进程(Process)事件
// 进程事件
process.on('exit', (code) => {console.log(`进程退出,退出码: ${code}`);
});process.on('uncaughtException', (err) => {console.error('未捕获的异常:', err);process.exit(1);
});process.on('unhandledRejection', (reason, promise) => {console.error('未处理的Promise拒绝:', reason);
});process.on('warning', (warning) => {console.warn('进程警告:', warning);
});// 信号事件
process.on('SIGINT', () => {console.log('收到 SIGINT 信号,优雅关闭');process.exit(0);
});process.on('SIGTERM', () => {console.log('收到 SIGTERM 信号,优雅关闭');process.exit(0);
});
7. 子进程事件
const { spawn, fork } = require('child_process');const child = spawn('ls', ['-la']);child.on('exit', (code, signal) => {console.log(`子进程退出,退出码: ${code}`);
});child.on('close', (code) => {console.log(`子进程标准流关闭,退出码: ${code}`);
});child.on('error', (err) => {console.error('启动子进程失败:', err);
});child.stdout.on('data', (data) => {console.log('子进程输出:', data.toString());
});child.stderr.on('data', (data) => {console.error('子进程错误输出:', data.toString());
});
8. 网络套接字事件
const net = require('net');const server = net.createServer((socket) => {console.log('客户端连接');socket.on('data', (data) => {console.log('接收到数据:', data.toString());socket.write('ECHO: ' + data);});socket.on('end', () => {console.log('客户端断开连接');});socket.on('error', (err) => {console.error('套接字错误:', err);});socket.on('close', () => {console.log('连接完全关闭');});
});server.on('error', (err) => {console.error('服务器错误:', err);
});server.listen(8124, () => {console.log('TCP服务器运行在端口 8124');
});
9. 定时器事件
const { setTimeout, setInterval } = require('timers');// 虽然定时器不是EventEmitter,但可以模拟事件模式
class TimerEmitter extends require('events') {startTimer(delay) {setTimeout(() => {this.emit('timeout', `定时器在 ${delay}ms 后触发`);}, delay);}startInterval(interval) {setInterval(() => {this.emit('tick', new Date());}, interval);}
}const timer = new TimerEmitter();timer.on('timeout', (message) => {console.log(message);
});timer.on('tick', (time) => {console.log('定时触发:', time.toLocaleTimeString());
});timer.startTimer(1000);
timer.startInterval(2000);
10. 自定义事件的高级用法
const EventEmitter = require('events');class AdvancedEmitter extends EventEmitter {constructor() {super();this.requestCount = 0;}makeRequest(data) {this.requestCount++;// 在触发事件前进行预处理const processedData = this.preprocess(data);// 触发请求事件this.emit('request', {id: this.requestCount,data: processedData,timestamp: new Date()});// 模拟异步响应setTimeout(() => {this.emit('response', {requestId: this.requestCount,result: `Processed: ${processedData}`,success: true});}, 1000);}preprocess(data) {return data.toString().toUpperCase();}
}const emitter = new AdvancedEmitter();// 监听多个事件
emitter.on('request', (request) => {console.log('请求 #', request.id, '数据:', request.data);
});emitter.on('response', (response) => {console.log('响应 #', response.requestId, '结果:', response.result);
});// 使用
emitter.makeRequest('hello world');
