Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

705
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda