收听Node.js中的所有已发送事件

Chr*_* W. 65 javascript events json node.js

在Node.js中有没有办法监听EventEmitter对象发出的所有事件?

例如,你能做点什么......

event_emitter.on('',function(event[, arg1][, arg2]...) {}
Run Code Online (Sandbox Code Playgroud)

我的想法是,我想抓住服务器端吐出的所有事件EventEmitter,JSON.stringify事件数据,通过websockets连接发送它,在客户端将它们作为事件进行改造,然后在客户端进行事件处理.

Mar*_*tin 72

我知道这有点老了,但到底是什么,这是你可以采取的另一种解决方案.

您可以轻松地修补要捕获所有事件的发射器的发射功能:

function patchEmitter(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);
  }
}
Run Code Online (Sandbox Code Playgroud)

这是非常简单的代码,应该适用于任何发射器.

  • 建议更改行 oldEmit.apply(emitter,arguments); 返回oldEmit.apply(发射器,参数); (3认同)

Hen*_*teg 39

如上所述,此行为不在node.js核心中.但你可以使用hij1nx的EventEmitter2:

https://github.com/hij1nx/EventEmitter2

它不会使用EventEmitter破坏任何现有代码,但会添加对命名空间和通配符的支持.例如:

server.on('foo.*', function(value1, value2) {
  console.log(this.event, value1, value2);
});
Run Code Online (Sandbox Code Playgroud)

  • 它还有一个`emitter.onAny(listener)`方法,它添加了一个在发出任何事件时将被触发的监听器. (11认同)
  • 这对于在事件发射器中烘焙的node.js的任何现有内部使用都没有帮助,尽管这是请求者正在寻找的内容.我认为http://stackoverflow.com/a/18087021/455556完美地回答了这个问题 (4认同)
  • @SalmanPK `onAny` 如何传递事件名称?因为我试过 `obj.onAny(function() {console.log(arguments);});` 并且我只有没有名字的事件参数...... (3认同)

pra*_*mil 16

使用ES6课程非常简单:

class Emitter extends require('events') {
    emit(type, ...args) {
        console.log(e + " emitted")
        super.emit(type, ...args)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这可以通过其他人创建的 EventEmitter 的现有实例来完成吗? (3认同)

Dav*_*ruz 6

请注意,上述所有可行的解决方案都将涉及对node.js EventEmitter内部实现的某种黑客攻击。

这个问题的正确答案是:默认的EventEmitter实现不支持该功能,您需要解决一下

如果您查看EventEmitter的node.js源代码,您会看到,当没有侦听器附加到特定事件类型时,它将返回而无需任何进一步的操作,因为它正在尝试从哈希中检索回调函数。根据事件类型:

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

这就是为什么类似的东西eventEmitter.on('*', ()=>...)默认情况下无法工作的原因。


Vic*_*der 6

从 Node.js v6.0.0 开始,class完全支持新的语法和参数扩展运算符,因此通过简单的继承和方法覆盖来实现所需的功能非常安全且相当容易:

'use strict';
var EventEmitter = require('events');

class MyEmitter extends EventEmitter {
  emit(type, ...args) {
    super.emit('*', ...args);
    return super.emit(type, ...args) || super.emit('', ...args);
  }
}
Run Code Online (Sandbox Code Playgroud)

此实现依赖于返回/取决于事件是否由某个侦听器处理的原始emit方法的事实。请注意,覆盖包含一条语句,因此我们为其他消费者保留此行为。EventEmittertruefalsereturn

这里的想法是使用星形事件 ( *) 创建在每个事件上执行的处理程序(例如,出于记录目的),并使用空事件 ( '') 作为默认或捕获所有处理程序,如果没有其他事件捕获,则执行事件。

我们确保首先调用 star( *) 事件,因为在error没有任何处理程序的事件的情况下,结果实际上是抛出异常。有关详细信息,看一看的实施EventEmitter

例如:

var emitter = new MyEmitter();

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
Run Code Online (Sandbox Code Playgroud)

最后,如果 EventEmitter 实例已经存在,但您想将该特定实例调整为新行为,可以通过在运行时修补该方法轻松完成,如下所示:

emitter.emit = MyEmitter.prototype.emit;
Run Code Online (Sandbox Code Playgroud)