Eventos y EventEmitter
Node.js utiliza un modelo basado en eventos para gestionar operaciones asíncronas. Un evento representa una acción o suceso que ocurre en el sistema, como la llegada de datos, la finalización de una tarea o la interacción del usuario. Este enfoque permite que el código responda a sucesos de manera eficiente, sin bloquear el event loop.
EventEmitter
La clase EventEmitter es el núcleo del sistema de eventos en Node.js. Permite crear objetos que pueden emitir eventos y escuchar su ocurrencia mediante listeners. La clase EventEmitter se encuentra en el módulo events, que es nativo de Node.js.
Ejemplo básico de EventEmitter:
import EventEmitter from 'events';
const emisor = new EventEmitter();
// Registrar un listener para el evento 'mensaje'
emisor.on('mensaje', (texto) => {
console.log(`Se recibió el mensaje: ${texto}`);
});
// Emitir el evento 'mensaje'
emisor.emit('mensaje', 'Hola mundo!');
En este ejemplo, se crea un emisor de eventos, se registra un listener para el evento 'mensaje' y luego se dispara el evento con emit. Cuando se emite, se ejecuta automáticamente la función asociada.
Métodos importantes
on(evento, listener): Registra un listener que se ejecutará cada vez que se emita el evento.once(evento, listener): Registra un listener que solo se ejecutará la primera vez que ocurra el evento.emit(evento, ...args): Emite un evento, ejecutando todos los listeners asociados.removeListener(evento, listener): Elimina un listener específico.removeAllListeners(evento): Elimina todos los listeners de un evento.
Ejemplo con once y removeListener:
function saludo(nombre) {
console.log(`Hola, ${nombre}`);
}
emisor.once('saludo', saludo);
emisor.emit('saludo', 'Ana'); // Se ejecuta
emisor.emit('saludo', 'Carlos'); // No se ejecuta, porque fue 'once'
emisor.on('despedida', saludo);
emisor.removeListener('despedida', saludo);
emisor.emit('despedida', 'Ana'); // No se ejecuta
Uso práctico
El patrón de eventos es muy común en Node.js, especialmente en módulos que manejan operaciones asíncronas o flujos de datos, como:
fspara leer archivos mediante streams (fs.createReadStream).httppara gestionar peticiones y respuestas en servidores.- Librerías como
Socket.IOoEventEmitterpersonalizados para aplicaciones en tiempo real.
Buenas prácticas
Al trabajar con eventos y EventEmitter, es recomendable:
- Evitar listeners anónimos si luego se necesita eliminarlos.
- Registrar y limpiar listeners de manera controlada para prevenir fugas de memoria.
- Usar
oncecuando solo se necesita ejecutar la función una vez. - Mantener la lógica de los listeners simple y delegar tareas complejas a funciones externas.