admin管理员组

文章数量:1410674

I'm looking for a simple pubsub implementation I can use in nodejs or a simliar way. I only need it on the server side so no fancy faye needed.

I want to have following ability:

Module A publishes event 'X' Module B subscribes to event 'X' without knowing anything about module A(except maybe what params are sent)

I tested out this simple implementation .js/blob/master/src/pubsub.js which really does its job

The current problem I have with a simple pubsub implementation is that I cannot simply subscribe to events.

If Module A publishes an Event but Module B was nowhere required it will never receive the event from module A. A soon as Module A requires Module B before publishing an event it works of course. But this is rather unpleasant.

So in short form: I'm looking for a design pattern which pairs well with nodejs and allows me to write modules very independently (loose coupling) that can municate over events. What approaching are you guys remend?

I also looked at nodejs eventemitter but couldn't find a good use of it (maybe I just can't see it?)

Update: I looked a little bit further into eventemitter and came up with this:

emitter.js

var events = require('events');
var emitter = new events.EventEmitter;

module.exports = emitter;

moduleA.js

var emitter = require('./emitter.js');
require('./moduleB.js'); // this shows off my problem

emitter.emit('moduleA');

moduleB.js

var emitter = require('./emitter.js');

emitter.on('moduleA', function () {
    console.log('reacted to event from moduleA');
});

This shows of my "problem" but I'm not sure if there is a way around. Maybe my approach is pletely wrong but on browser side this should work because all code is preloaded on pageload

I'm looking for a simple pubsub implementation I can use in nodejs or a simliar way. I only need it on the server side so no fancy faye needed.

I want to have following ability:

Module A publishes event 'X' Module B subscribes to event 'X' without knowing anything about module A(except maybe what params are sent)

I tested out this simple implementation https://github./federico-lox/pubsub.js/blob/master/src/pubsub.js which really does its job

The current problem I have with a simple pubsub implementation is that I cannot simply subscribe to events.

If Module A publishes an Event but Module B was nowhere required it will never receive the event from module A. A soon as Module A requires Module B before publishing an event it works of course. But this is rather unpleasant.

So in short form: I'm looking for a design pattern which pairs well with nodejs and allows me to write modules very independently (loose coupling) that can municate over events. What approaching are you guys remend?

I also looked at nodejs eventemitter but couldn't find a good use of it (maybe I just can't see it?)

Update: I looked a little bit further into eventemitter and came up with this:

emitter.js

var events = require('events');
var emitter = new events.EventEmitter;

module.exports = emitter;

moduleA.js

var emitter = require('./emitter.js');
require('./moduleB.js'); // this shows off my problem

emitter.emit('moduleA');

moduleB.js

var emitter = require('./emitter.js');

emitter.on('moduleA', function () {
    console.log('reacted to event from moduleA');
});

This shows of my "problem" but I'm not sure if there is a way around. Maybe my approach is pletely wrong but on browser side this should work because all code is preloaded on pageload

Share Improve this question edited Aug 13, 2013 at 20:10 Playerwtf asked Aug 13, 2013 at 19:23 PlayerwtfPlayerwtf 3111 gold badge4 silver badges13 bronze badges 6
  • Your approach should work, but if you load moduleA.js before moduleB.js with that code it might emit the event before B does listen to it. Try to exchange their order – Bergi Commented Aug 13, 2013 at 20:17
  • That's exactly what I currently see. When module B listens to module A but is not loaded before Module A emits the event it simply does not catch the event. Which is very logically because the module cannot listen to an event if it is not required somewhere. But I still think this is rather bad and will lead to errors where someone can easily forget to 'preload' a module – Playerwtf Commented Aug 13, 2013 at 20:42
  • I guess an actual usecase would only include asynchronous events, i.e. nothing is fired right away when the module is executed so the load order is not important. – Bergi Commented Aug 14, 2013 at 12:22
  • Thats actually not true. I have an use case where I have exactly this problem. It's a simple websocket app. When the first user connects I fire a 'connect' event but the module that handles the connect event wasn't required anywhere. So there is actually no one subscribed to that event. What I do for now is 'preloading' modules. I define in a json file which modules should be preloaded up on start of the app. This works for my case. – Playerwtf Commented Aug 14, 2013 at 20:00
  • Yeah, of course they all need to be loaded by the main script when starting up. My point was that the order of loading is irrelevant, because when the first signal is emitted (when a socket connects) asynchronously all modules are loaded already and can't miss it. – Bergi Commented Aug 14, 2013 at 20:04
 |  Show 1 more ment

1 Answer 1

Reset to default 7

Here's a simple template for basic event plumbing use node's core events module.

//modA.js
var events = require('events');
var emitter = new events.EventEmitter;

function funcA() {
  console.log('[email protected] executing');
  emitter.emit('funcA');
}

module.exports = {
  funcA: funcA,
  emitter: emitter
};

//modB.js
var events = require('events');
var emitter = new events.EventEmitter;

function funcB() {
  console.log('modB.funcB executing');
  emitter.emit('funcB');
}

module.exports = {
  funcB: funcB,
  emitter: emitter
};

//glue.js
var modA = require('./modA');
var modB = require('./modB');
modA.emitter.on('funcA', modB.funcB);
modA.funcA();

node glue.js
[email protected] executing
modB.funcB executing

本文标签: javascriptpubsub design pattern for nodejsStack Overflow