EventEmitter没有发射

时间:2014-02-04 17:52:14

标签: javascript node.js

我有这个节点js脚本:

var EventEmitter = require('events').EventEmitter,
    util = require('util');

var pfioObject = function () {
    this.init = function () {
        console.log("started server");
    };
    this.deinit = function () {
        console.log("stopped server");
    };
    this.read_input = function () {
        return 0;
    };
};
console.log(util.inspect(EventEmitter, false, null)); //<--- this shows no method emit either

var pfio = new pfioObject();

var pfioServer = function () {
    this.prev_state = 0;
    this.start = function () {
        pfio.init();
        this.watchInputs();
    };

    this.stop = function () {
        pfio.deinit();
    };
}

util.inherits(pfioServer, EventEmitter);

// add some event emitting methods to it
pfioServer.prototype.watchInputs = function () {
    var state = pfio.read_input();

    if (state !== this.prev_state) {
        this.emit('pfio.inputs.changed', state, this.prev_state);
        this.prev_state = state;
    }

    setTimeout(this.watchInputs, 10); // going to put this on the event loop next event, more efficient
};

// export the object as a module
module.exports = new pfioServer();

由于某种原因,节点错误表明没有像emit这样的对象,我已经npm install events查看是否会修复它,它没有。我不确定为什么我会收到此错误。

我认为在我的代码中某处存在错误但我无法看到任何内容。

要运行此代码,我有另一个脚本执行此操作:

var pfioServer = require('./pfioServer'),
util = require('util');

console.log(util.inspect(pfioServer, false, null)); //<--- this line shows the pfioServer with out the prototype function watchInputs

pfioServer.start();

修改

我想我可能错过了关于事件发射器内容的一些重要代码,我正在研究事件发射器类的实例化

轻微变化

所以我没有继承EventEmitter,而是通过var emitter = new EventEmitter()

实例化它

然后我在util.inspect中得到关于对象必须是对象的错误或者为空。

尚未成功。

3 个答案:

答案 0 :(得分:1)

原因是这一行:

setTimeout(this.watchInputs, 10);

当超时被触发并且this.watchInputs被调用时,它已经失去了它的上下文。

您需要使用this显式设置该调用的上下文对象(换句话说,该方法应指向的bind):

setTimeout(this.watchInputs.bind(this), 10);

答案 1 :(得分:1)

我发现必须更改两件事才能使第一个代码块无错误地运行:

  • 明确地实例化events.EventEmitter()

var events = require('events'); var EventEmitter = new events.EventEmitter();

  • 将来电更改为util.inherits

util.inherits(pfioServer, events.EventEmitter);

让服务器运行的最后一件事是robertklep写的:setTimeout()中修复binding

setTimeout(this.watchInputs.bind(this), 10);

答案 2 :(得分:1)

console.log(util.inspect(EventEmitter, false, null));
// this shows no method emit either

EventEmitter构造函数没有这样的方法。 EventEmitter.prototype有。要打印(不可枚举的).prototype属性,可以使用util.inspect(EventEmitter, {showHidden: true})作为评论中提到的@Emissary。

// this line shows the pfioServer with out the prototype function watchInputs
console.log(util.inspect(pfioServer, false, null));

是。 util.inspect不显示继承的属性,只显示pfioServer实例本身显示的属性。

setTimeout(this.watchInputs, 10);
// going to put this on the event loop next event, more efficient

我宁愿说它阻止了无限循环...但是,这也会破坏下一次调用中的this上下文,这不再是你的pfioServer实例。见How to access the correct `this` context inside a callback?

但是,在你的情况下,我没有看到使用构造函数和继承原型的必要性。您只是导出一个单例对象,您可以使用对象文字进行实例化,并通过变量名称进行引用。