Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

711
Vistas
Creando un Singleton EventEmittor en Nodejs & Express Project

Estoy tratando de crear un patrón de editor-suscriptor con eventEmitters de Nodejs para mi proyecto API de nodejs/express. Mi caso de uso es bastante simple:

  1. Quiero emitir eventos desde varios lugares en mi proyecto. Por ejemplo, emitir un evento cuando se crea un nuevo usuario.
  2. Entonces quiero un solo lugar, donde escucho todos los eventos y decido qué acciones tomar.

Esto requerirá una instancia singleton de eventEmitter porque las llamadas 'emit' y 'on' deben ocurrir en la misma instancia del objeto 'event'.

Para lograrlo, así es como se ve mi index.js :

 const express = require('express') const app = express() const bodyParser = require('body-parser') const routes = require('./api/routes') const EventEmitter = require("events"); const eventEmitter = new EventEmitter(); const eventListeners = require('../src/subscribers/events'); //const eventSubs = new eventListeners(); app.use(eventListeners.eventSubscribers()); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.set('eventEmitter', eventEmitter); app.get('/', (req, res) => res.send('App is working')) app.use('/api', routes) app.listen(3000, () => console.log('Example app listening on port 3000!')) module.exports = { app }

Así es como se ve mi función de middleware/controlador (donde estoy emitiendo un evento):

 const createUser = async (req, res, next) => { var user = req.body try { console.log('in controller'); await newUser(user) console.log(req.app.get('eventEmitter')); req.app.get('eventEmitter').emit('USER_CREATED', {email: user.email, name: user.name}) res.status(200).send({success: true}); next() } catch(e) { console.log(e.message) res.sendStatus(500) && next(e) } }

Y así es como se ve mi archivo de suscriptor de eventos :

 const eventSubscribers = (req) => { const eventEmitter = req.app.get('eventEmitter'); eventEmitter.on('USER_CREATED', ({ email, name }) => { console.log('event fired and captured') }) }

Con esto, el evento se emite, pero el suscriptor del evento no se activa. Creo que hay algún problema con la forma en que accedo a los objetos de solicitud/aplicación en mi suscriptor. Además, estoy recibiendo

 TypeError: eventListeners.eventSubscribers is not a function

error en mi archivo index.js. Preguntas que tengo:

  1. ¿Es esta la forma correcta de crear un patrón de publicador/suscriptor?
  2. ¿Cómo accedo a instancias de objetos de solicitud/aplicación en mi suscriptor de eventos?
  3. ¿Cuál es la mejor manera de asegurarse de que el archivo de suscriptor de eventos se carga cuando se carga la aplicación?
over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Suponiendo que todo lo demás esté configurado correctamente por usted,
Creo que la causa del error que mencionas

 TypeError: eventListeners.eventSubscribers is not a function

es que no se pasa ninguna función al middleware, es decir, como un middleware, ¿no debería simplemente pasar eventListeners.eventSubscribers de esta manera?

 app.use(eventListeners.eventSubscribers);

en vez de así

 app.use(eventListeners.eventSubscribers());

Si comparamos las dos expresiones anteriores, express no puede pasar el objeto de solicitud en el segundo caso, ya que lo está llamando, pero esta llamada de función no devuelve nada al express, es decir, un tipo de vacío, pero en el primer caso desde que pasó el objeto de función referencia a express, luego lo llama como middleware (como una devolución de llamada más tarde y pasa el objeto de solicitud mientras lo llama).

Alternativamente, creo que no necesita usar middleware para usar EventEmitter, puede mantener una única instancia personalizada global que consiste en EventEmitter como su propiedad y todos los eventos diferentes que desea escuchar, y luego simplemente usarlos donde los necesite .Puede usar EventEmitter como una propiedad de este personalizado para emitir eventos en cualquier módulo que desee importando este módulo personalizado allí.

Este es el ejemplo de trabajo a continuación

archivo index.js/archivo de entrada

 const express = require('express') const app = express() const bodyParser = require('body-parser') const routes = require("./userRoute"); //const eventSubs = new eventListeners(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.get('/', (req, res) => res.send('App is working')) app.use('/api', routes); app.listen(3000, () => console.log('Example app listening on port 3000!'))

Esta es nuestra instancia personalizada de singleton global que utiliza EventEmitter como propiedad.

 const { EventEmitter } = require("events"); class CustomEventEmitter { eventEmitter; constructor() { this.eventEmitter = new EventEmitter(); this.initialize(); } getEventEmitter() { return this.eventEmitter; } initialize() { this.eventEmitter.on('USER_CREATED', ({ email, name }) => { console.log('event fired and captured with data', email, name); }); } } module.exports = new CustomEventEmitter();

y aquí usamos nuestro módulo global CustomEventEmitter en nuestras rutas de solicitud, es decir, userRoute.js

 const router = require("express").Router(); const customEventEmitter = require("./CustomEventEmitter"); const createUser = async (req, res, next) => { var user = req.body try { console.log('in controller'); // await newUser(user) customEventEmitter.getEventEmitter().emit('USER_CREATED', { email: user.email, name: user.name }) res.status(200).send({ success: true }); next() } catch (e) { console.log(e.message) res.sendStatus(500) && next(e) } } router.post("/createUser", createUser) module.exports = router;
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda