重写节点 eventEmitter.on 并关闭日志记录不起作用

web*_*oob 1 javascript closures node.js eventemitter

我正在尝试找出 SPA 中的一个问题,即某个事件被触发太多次。考虑到这一点,我想重写节点的eventEmitter.on函数来添加一些登录,然后调用原始函数。这让我在/sf/answers/729943021/上找到了关于覆盖的答案window.alert,我想出了以下代码:

// Ignore `state` here but it essentially means I can access `eventEmitter` all over my app.
var EventEmitter = ('events')   
state.eventEmitter = new EventEmitter()
state.eventEmitter.on = (function (original) {
    return function (name, callback) {
        console.log('On Called for %s', name)
        original(name, callback)
    }
})(state.eventEmitter.on)
Run Code Online (Sandbox Code Playgroud)

这不起作用。该事件根本没有触发,我在控制台中没有看到任何内容。

我究竟做错了什么?

注意:我还有其他方法可以追踪我的原始问题,但我很感兴趣为什么上面的代码不起作用。

Dom*_*rtl 5

我尝试了你的代码,它看起来大部分都很好,但当我运行它时,我收到以下错误:

Cannot read property '_events' of undefinedEventEmitter 的内部错误

这是因为传递原始.on()函数的方式在调用时会丢失上下文(此参数)。

为了避免这种情况,通过调用将函数绑定到事件发射器state.eventEmitter.on.bind(state.eventEmitter)。我还注意到您忘记了返回原始函数的结果,因为它on()是可链接的。

此外,如果没有人正在侦听事件,您的重写函数也不会被调用。

这是经过上述修改的代码

var EventEmitter = require('events');
state.eventEmitter = new EventEmitter();
state.eventEmitter.on = (function (original) {
    return function (name, callback) {
        console.log('On Called for %s', name);
            return original(name, callback);
        }
})(state.eventEmitter.on.bind(state.eventEmitter));

state.eventEmitter.on('my_event', function () {
    console.log('my_event has been called');
});

state.eventEmitter.emit('my_event');
Run Code Online (Sandbox Code Playgroud)

得到以下输出:

On Called for my_event
my_event has been called
Run Code Online (Sandbox Code Playgroud)