Nodejs EventEmitter - 定义侦听器函数的范围

Posted

技术标签:

【中文标题】Nodejs EventEmitter - 定义侦听器函数的范围【英文标题】:Nodejs EventEmitter - Define scope for listener function 【发布时间】:2011-12-21 18:39:39 【问题描述】:

我想要这样的作品:

var Events=require('events'),
    test=new Events.EventEmitter,
    scope=
        prop:true
    ;

test.on('event',function() 
   console.log(this.prop===true);//would log true
);
test.emit.call(scope,'event');

但是,不幸的是,监听器甚至没有被调用。有没有办法用 EventEmitter 做到这一点?我可以Function.bind 给听众,但是,我真的希望EventEmitter 有一些特殊的(或明显的;)方法来做到这一点......

感谢您的帮助!

【问题讨论】:

【参考方案1】:

不是,因为侦听器中的this 值是事件发射器对象。

但是你能做的就是这个

var scope = 
  ...
;
scope._events = test._events;
test.emit.call(scope, ...);

您的事件处理程序没有被调用的原因是因为所有处理程序都存储在._events 中,所以如果您将._events 复制过来,它应该可以工作。

【讨论】:

Doh,现在看起来很明显。谢谢你的光芒:)。 由于在从 EventEmitter 扩展的对象上创建的 _events 属性不是其记录的公共接口的一部分,这是明智的建议吗? @RobRaisch 不,但不太可能改变。 截至今天,对于 Node 0.10.38、0.12.4 和 IO.JS 2.2.1,这种方法仍然可以正常工作。时间证明:) 很好的答案!谢谢!【参考方案2】:

那是行不通的,emit 只有一种方便的方式来传递参数,而没有用于设置this。看起来你必须自己做绑定的东西。但是,您可以将其作为参数传递:

test.on('event',function(self) 
   console.log(self.prop===true);//would log true
);
test.emit('event', scope);

【讨论】:

这样简单!但是,不幸的是,如果发射不在您的控制之下,但框架无法解决问题。 所有相反的证据。 4 年后,公认的答案在 Node JS 的每个版本中仍然有效:0.10.38、0.12.4、IO.JS 2.2.1。像魅力一样工作:)【参考方案3】:

我在 Google 搜索 NPM 中处理此问题的包时遇到了这篇文章:

var ScopedEventEmitter = require("scoped-event-emitter"),
    myScope = ,
    emitter = new ScopedEventEmitter(myScope);

emitter.on("foo", function() 
    assert(this === myScope);
);

emitter.emit("foo");

完全披露,这是我写的一个包。我需要它,这样我就可以拥有一个具有 EventEmitter 属性的对象,该属性为包含对象发出。 NPM包页面:https://www.npmjs.org/package/scoped-event-emitter

【讨论】:

接受的答案完美无缺,不需要整个额外的库:) 这叫代码复用。 “整个额外库”是一个 37 行的 javascript 文件,但由于它是一个已发布的包,因此您可以在许多项目中使用它,而无需寻找您添加了已接受答案的那个项目。此外,发布时不存在已接受的答案。

以上是关于Nodejs EventEmitter - 定义侦听器函数的范围的主要内容,如果未能解决你的问题,请参考以下文章

nodejs 事件EventEmitter

nodejs-08-EventEmitter

nodejs-08-EventEmitter

Nodejs 的 EventEmitter 和 Jquery 触发器

Nodejs学习笔记-----EventEmitter

NodeJS:如何调试“检测到 EventEmitter 内存泄漏。添加了 11 个侦听器”