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)
这不起作用。该事件根本没有触发,我在控制台中没有看到任何内容。
我究竟做错了什么?
注意:我还有其他方法可以追踪我的原始问题,但我很感兴趣为什么上面的代码不起作用。
我尝试了你的代码,它看起来大部分都很好,但当我运行它时,我收到以下错误:
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)