在对象构造器中集成 EventEmitter 以在原型方法中使用

Integrate EventEmitter in Object construtor to use in prototype methods

我有以下奇怪的问题: 我写了一个 "Class" 游戏。这个 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);
  });
};

这不起作用,因为 expected.Error 是:

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); 

在第二个例子的构造函数中。 但独立于评论或留下它,这种下降改变了一切。 为什么我需要这个?我呢?

也许你能帮上忙。亲切的问候。 马丁

您必须先将 util.inherits(Game, EventEmitter); 移动到 ,然后才能 开始向您的原型添加功能。 util.inherits() 干扰了原型,因此在此之前放置在其上的所有内容都将丢失。

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

更新示例 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 后缀部分。它仍然可用于向后兼容。
  • 可以使用 class 和扩展。
  • 可以在隐式绑定到 this 的 setInterval 中使用箭头函数,而不需要将其映射到自身。