在Object construtor中集成EventEmitter以在原型方法中使用

时间:2015-05-28 05:54:46

标签: javascript node.js eventemitter

我有以下奇怪的问题: 我写了一个" Class"游戏。这个类有一个构造函数和一个原型方法。我希望整个构造成为一个EventEmitter。所以我想我可以继承我的构造函数的event.EventEmitter。 它首先看起来如下:

game.js

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

/*
  Game factory
*/

function Game(catalogue, speed) {

  //EventEmitter.call(this);

  this.catalogue  = catalogue || null;
  this.speed      = speed || 10;  

}

Game.prototype.listen = function(){
  var self = this;
  setInterval(function(){
    self.emit('init', 0);
  }, 500);
}

util.inherits(Game, EventEmitter);
module.exports = Game;

我使用socket.io连接到客户端。在我的主套接字例程中,我使用以下代码来启动一个新游戏(实例化)

controller.js

socket.on('startGame', function(){      

  var myGame = new Game('default', 10);
  myGame.init();

  myGame.on('init', function(status){
    console.log('Did start with status code: ', status);
  });
};

这不能按预期工作。错误是:

Missing error handler on `socket`.
TypeError: undefined is not a function
    at Socket.<anonymous> 

当我在构造函数中使用emit事件时,它可以工作(当然,在console.js中没有myGame.listen()):

function Game(catalogue, speed) {


  //EventEmitter.call(this);

  this.catalogue  = catalogue || null;
  this.speed      = speed || 10;  

  var self = this;
  setInterval(function(){
    self.emit('init', (Math.random()*10).toFixed(0));
  }, 500)

}

那么这里有什么问题? 请注意,我不需要

EventEmitter.call(this); 

在第二个示例中的构造函数中。 但是,无论是对此进行评论还是将其留下,这种下降都会改变一切。 为什么我需要这个呢?我呢?

也许你可以提供帮助。亲切的问候。 马丁

2 个答案:

答案 0 :(得分:2)

您必须先将util.inherits(Game, EventEmitter);移至,然后再开始向原型添加功能util.inherits()插入原型,因此在此之前放置的任何东西都会丢失。

此外,当你从另一个对象(如EventEmitter)继承时,你真的应该调用父构造函数(EventEmitter.call(this)),因为它可能需要对它自己做一些初始化。

答案 1 :(得分:0)

使用Node.js v11.12.0更新的示例

const EventEmitter = require('events');

module.exports = class Game extends EventEmitter {
    constructor(catalogue, speed) {
        super();
        this.catalogue = catalogue || null;
        this.speed = speed || 10;
    }

    listen() {
        setInterval(() => {
            self.emit('init', 0);
        }, 500);
    }
};

let myGame = new Game('default', 10);
myGame.listen();
myGame.on('init', status => {
    console.log('Did start with status code: ', status);
});

这里有一些新颖的新东西。

  • 不需要require('events')。EventEmitter后缀部分不再存在。仍然可以向后兼容。
  • 可以使用类并进行扩展。
  • 可以在setInterval中使用箭头函数,该函数隐式绑定到this,而无需将其映射到self。