Node.js EventEmitter和多层次的inheritance
我试图找出使用Node.js EventEmitter
类时多级inheritance的最佳方法。
设置是我正在开发一个MVC框架的Node.js使用控制器,可以有基地控制器,但控制器可以发出的事件也发出同样的事件在其基本控制器。 到目前为止我有:
var events = require('events'); var util = require('util'); var Controller = function() { }; util.inherits(Controller, events.EventEmitter); var baseController = new Controller(); baseController.on('request', function() { console.log('Calling request event on baseController'); }); var homeController = new Controller(); homeController.prototype = baseController; homeController.on('request', function() { console.log('Calling request event on homeController'); }); homeController.emit('request');
…但是只输出“ homeController上的调用请求事件 ”,我希望这两个“请求”事件触发。 我该怎么做呢? 也许我需要彻底改变我的方法?
更新:感谢大家的帮助。 正如Naor Biton所说,baseController和homeController之间没有inheritance关系,因为“prototype”属性只对构造函数很重要。 我总是让我的构造函数和对象实例混合起来。
我最终解决了以下问题:
var events = require('events'); var util = require('util'); var Controller = function() { }; util.inherits(Controller, events.EventEmitter); Controller.createBaseController = function() { var BaseController = function() { }; util.inherits(BaseController, Controller); return new BaseController(); }; Controller.inheritController = function(baseController) { var NewController = function() { }; NewController.prototype = baseController; return new NewController(); }; var baseController = Controller.createBaseController(); baseController.on('request', function() { console.log('Calling request event on baseController'); }); var homeController = Controller.inheritController(baseController); homeController.on('request', function() { console.log('Calling request event on homeController'); }); homeController.emit('request');
在你的例子中, homeController和baseController之间没有任何inheritance关系。 另外,这一行:
homeController.prototype = baseController;
是多余的,因为prototype属性只对构造函数很重要。
如果你想设置baseController,那么扩展/从它inheritance的任何人将有“请求”监听器分配给它,首先你应该这样定义它:
var BaseController = function(){ this.on('request', function(){ console.log('...'); }); }; BaseController.prototype = new events.EventEmitter(); BaseController.prototype.constructor = BaseController;
如果你可以在一个初始化方法中进行处理程序赋值(在构造函数中进行工作通常是不好的devise),那将会更好:
var BaseController = function(){}; BaseController.prototype = new events.EventEmitter(); BaseController.prototype.init = function(){ this.on('request', function(){ console.log('...'); }); };
然后,所有你需要在你的HomeController中扩展它是这样做的:
var HomeController = function(){}; HomeController.prototype = new BaseController(); var homeController = new HomeController(); homeController.init(); // If you went with the initialization approach I offered...
请注意,除非你必须这么做,否则在JS中创build长的inheritance链并不是很好或可维护。 如果可以的话,我鼓励你避免这样做,并尝试find一个更可维护的解决scheme。
在你的例子中, homeController
和baseController
都有相同的原型(你可以使用getPrototypeOf
来validation.prototype
是一个函数的属性 。
如果你想直接将一个对象的原型设置为另一个对象而不使用函数并设置其原型,那么可以使用Object.create
顺便说一句,这是我的做法(使用较less的原型inheritance和更多的结构子types)。
function Controller(){ var obj = new events.EventEmitter(); // Add stuff to controller here obj.on("request",function(){ console.log('Calling request event on baseController'); }); return obj; } function HomeController(){ var obj = new Controller(); obj.on('request', function() { console.log('Calling request event on homeController'); }); return obj; } var homeController = new HomeController(); // can create a Controller and add // an event just fine. If you want explicit // structural subtyping we need HomeController homeController.emit("request");