Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

703
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!