Skip to content Skip to sidebar Skip to footer

Listen To All Emitted Events In Node.js

In Node.js is there any way to listen to all events emitted by an EventEmitter object? e.g., can you do something like... event_emitter.on('',function(event[, arg1][, arg2]...) {}

Solution 1:

I know this is a bit old, but what the hell, here is another solution you could take.

You can easily monkey-patch the emit function of the emitter you want to catch all events:

functionpatchEmitter(emitter, websocket) {
  var oldEmit = emitter.emit;

  emitter.emit = function() {
      var emitArgs = arguments;
      // serialize arguments in some way.
      ...
      // send them through the websocket received as a parameter
      ...
      oldEmit.apply(emitter, arguments);
  }
}

This is pretty simple code and should work on any emitter.

Solution 2:

As mentioned this behavior is not in node.js core. But you can use hij1nx's EventEmitter2:

https://github.com/hij1nx/EventEmitter2

It won't break any existing code using EventEmitter, but adds support for namespaces and wildcards. For example:

server.on('foo.*', function(value1, value2) {
  console.log(this.event, value1, value2);
});

Solution 3:

With ES6 classes it's very easy:

classEmitterextendsrequire('events') {
    emit(type, ...args) {
        console.log(type + " emitted")
        super.emit(type, ...args)
    }
}

Solution 4:

Be aware that all solutions described above will involve some sort of hacking around node.js EventEmitter internal implementation.

The right answer to this question would be: the default EventEmitter implementation does not support that, you need to hack around it.

If you take a look on node.js source code for EventEmitter, you can see listeners are retrieved from a hash using event type as a key, and it will just return without any further action if the key is not found:

https://github.com/nodejs/node/blob/98819dfa5853d7c8355d70aa1aa7783677c391e5/lib/events.js#L176-L179

That's why something like eventEmitter.on('*', ()=>...) can't work by default.

Solution 5:

Since Node.js v6.0.0, the new class syntax and argument spread operator is fully supported, so it's pretty safe and fairly easy to implement the desired functionality with simple inheritance and an method override:

'use strict';
varEventEmitter = require('events');

classMyEmitterextendsEventEmitter {
  emit(type, ...args) {
    super.emit('*', ...args);
    returnsuper.emit(type, ...args) || super.emit('', ...args);
  }
}

This implementation relies on the fact that the original emit method of the EventEmitter returns true/false depending if the event was handled by some listener or not. Notice that the override includes a return statement, so we keep this behavior for other consumers.

Here the idea is to use the star event (*) to create handlers that gets executed on every single event (say, for logging purposes) and the empty event ('') for a default or catch all handler, that gets executed if nothing else catches that event.

We make sure to call the star (*) event first, because in case of error events without any handlers, the result is actually an exception being thrown. For more details, take a look at the implementation of the EventEmitter.

For example:

var emitter = newMyEmitter();

emitter.on('foo', () =>console.log('foo event triggered'));
emitter.on('*', () =>console.log('star event triggered'));
emitter.on('', () =>console.log('catch all event triggered'));

emitter.emit('foo');
    // Prints://   star event triggered//   foo event triggered

emitter.emit('bar');
    // Prints://   star event triggered//   catch all event triggered

Finally, if an EventEmitter instance already exists but you want to adjust that specific instance to the new behavior, it can be easily done by patching the method at runtime like this:

emitter.emit = MyEmitter.prototype.emit;

Post a Comment for "Listen To All Emitted Events In Node.js"