如何在现有对象上调用EventEmitter

时间:2017-12-20 23:24:57

标签: node.js constructor eventemitter

我想将现有对象设置为EventEmitter,例如:

.cabal

但是,emitter.on是未定义的,而不是函数。

4 个答案:

答案 0 :(得分:2)

我不确定你的想法在哪里:

 EventEmitter.call(emitter);

会使用所有EventEmitter功能神奇地赋予您的发射器对象权限。该语句的作用是调用EventEmitter构造函数并将其作为this参数传递给它。这将导致构造函数执行并可能在emitter对象上设置一些数据,但它不会以任何方式将EventEmitter原型附加到您的对象,因此EventEmitter上的任何方法都可以原型未绑定到您的对象,因此.on()undefined

根据您可以控制和正在尝试完成的内容,有多种方法可以采用现有对象的功能。

如果您控制要成为EventEmitter的对象的定义,那么您只想从EventEmitter对象继承,然后您的对象将“成为”EventEmitter并且拥有所有方法和数据。

使用ES6类语法继承:

// myobj.js
const EventEmitter = require('events');

// inherit directly from EventEmitter
class MyObj extends EventEmitter {
  constructor () {
    super() 
  }
  // your other custom methods here
}

module.exports = MyObj;

然后,你会这样使用:

const MyObj = require("myobj.js");
let obj = new MyObj();
obj.on("hello", data => {
    console.log("got hello message");
});

obj.emit("hello", "to you");

如果您不控制要为其提供EventEmitter逻辑的对象的定义或构造,则需要确定是否要“成为”或“拥有”EventEmitter。

在“be a”路径中(除了它自己的函数之外,你希望你的对象“成为”EventEmitter,你可以混合使用EventEmitter对象的逻辑并将所有方法和数据添加到在创建自己的对象之后你自己的对象。这不是万无一失的,因为某些类型的对象可能依赖于你无法合适的私有数据。但是,它确实适用于许多对象。

对于EventEmitter,有一个特定的模块可以让您“混合”和EventEmitter。它被称为component-emitter on NPM并且非常易于使用。 socket.io使用它right here,这样它的套接字对象可以是EventEmitter

var Emitter = require('component-emitter');

/**
 * Mix in `Emitter`.
 */

Emitter(Socket.prototype);

对于“has a”路径,您只需创建一个EventEmitter对象并将其放在您自己对象的实例数据中,然后引用该特定对象以获取EventEmitter功能。您可以手动获取该对象并使用它,也可以使用一些方法自动使用它。这实现起来更简单,更简单,但在某些情况下使用起来并不方便(这一切都取决于你要做的事情的细节)。

class MyObj {
  constructor () {
    super() 
    this.myEmitter = new EventEmitter();
  }
  // your other custom methods here
  broadcast(msg, data) {
      // use the internal eventEmitter object we have in our instance data
      this.myEmitter.emit(msg, data);
  }
}

module.exports = MyObj;

答案 1 :(得分:0)

最简单的方法是使用ES6 Class syntax via the class keyword并使用extends关键字创建EventEmitter的子类。以下是如何通过Prototypal Inheritance创建自己的EventEmitter的简单示例。

// MyEmitter.js
const EventEmitter = require('events')

class MyEmitter extends EventEmitter {
  constructor () {
    super() 
    this.emit('created', 'New Instance of MyEmitter Created')
  }
}

module.exports = MyEmitter
// index.js
const MyEmitter = require('./MyEmitter')

// Create a new instance of MyEmitter
const emitter = new MyEmitter()

// Attach an Event Listener for the 'created' event
// Print whatever the message is to stdout
emitter.on('created', message => console.log)

答案 2 :(得分:0)

您可以通过两种方式解决此问题:要么扩展EventEmitter类,要么将emitter的原型设置为EventEmitter的原型;

// using es6 class 

class MyEmitter extends EventEmitter {
    constructor() {
        super();
    } 
}

const emitter = new MyEmitter();

emitter.on("greet", greet => console.log(greet));

emitter.emit("greet", "hello");

// if you want to use this on a different file you have to export the emitter object



// the second alternative if you don't want to use a class

const emitter = {};

Object.setPrototypeOf(emitter, events.prototype); 

// or

Object.setPrototypeOf(emitter, events.EventEmitter.prototype);

emitter.on("greet", greet => console.log(greet));

emitter.emit("greet", "hello");

答案 3 :(得分:0)

您仍然可以使用EventEmitter.call(emitter);

这是窍门:

const MyFunctionEmitter = function() { 
    EventEmitter.call(this, {objectMode: true});
     
    this.on('myevent', function(s) { 
      console.log(s)
    })

  }

MyFunctionEmitter.prototype = Object.create(EventEmitter.prototype, {
    constructor: { value: MyFunctionEmitter }
}); 

//inherit and apply native event emitter to our myFunction object
util.inherits(MyFunctionEmitter, EventEmitter);  
  
  var myEmitter = new MyFunctionEmitter() 
  myEmitter.emit('myevent', 'my event message')