Интегрируйте EventEmitter в конструктор объекта для использования в методах прототипа.

У меня следующая странная проблема: я написал игру "Класс". Этот класс имеет конструктор и один метод-прототип. Я хочу, чтобы вся конструкция была EventEmitter. Поэтому я подумал, что могу просто унаследовать event.EventEmitter для своего конструктора. Сначала это выглядело так:

игра.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 для подключения к клиенту. В моей основной процедуре сокета я использую следующий код для запуска новой игры (создание экземпляра)

контроллер.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 в конструкторе, оно работает (конечно, без myGame.listen() в console.js):

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

в конструкторе во втором примере. Но независимо от того, закомментировали это или оставили, эти падения что-то меняют. Зачем мне это вообще нужно? Я?

Может быть, вы можете помочь. Наилучшие пожелания. Мартин


person marschro    schedule 28.05.2015    source источник


Ответы (2)


Вы должны переместить свой util.inherits(Game, EventEmitter); в прежде чем начать добавлять функции в свой прототип. util.inherits() вмешивается в прототип, поэтому все, что было помещено на него до этого, теряется.

Кроме того, когда вы наследуете от другого объекта (например, EventEmitter), вам действительно следует вызывать родительский конструктор (EventEmitter.call(this)), потому что ему может потребоваться выполнить некоторую собственную инициализацию.

person mscdex    schedule 28.05.2015

Обновленный пример с 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 вместо необходимости сопоставлять это с собой.
person Dustin Graham    schedule 24.03.2019