我在某些类中使用EventEmitter
,但我真的很困惑事件监听和事件发射是否比调用对象方法更有效?
我希望对象能够侦听发送给它的许多事件,并且还向最初将事件发送到对象的对象以及其他一些对象发出大量事件。
我很困惑我何时应该使用函数来反过来调用其他对象方法等等。
答案 0 :(得分:2)
事件改善了模块解耦。这就是关于这个简单的问题:“我需要触摸多少个文件来修改或添加特征X?”
一个简单的例子:您有一个Web服务器,一个日志记录模块和一个启动脚本,它们在启动时将两者联系在一起。函数调用方式如下所示:
// Startup.js
var Startup = function() {
var logger = new Logger();
var server = new Server(logger);
};
// Logger.js
var Logger = function() {
};
Logger.prototype.log = function(msg) {
console.log(msg);
};
// Server.js
var Server = function(logger) {
this.logger = logger;
};
Server.prototype.start() {
this.logger.log("Start server...");
};
您可以看到Startup知道所有类,Server知道logger以及如何使用它。如果我想重命名Logger的功能日志来写,我必须触摸Logger和Server。
现在让我们看一下事件驱动的方法:
// Startup.js
var Startup = function() {
var logger = new Logger();
var server = new Server();
server.addListener(logger);
};
// Logger.js
var Logger = function() {
this.on("startup", function(msg) {
console.log(msg);
});
};
Logger.prototype.__proto__ = EventEmitter.prototype;
// Server.js
var Server = function() {
};
Server.prototype.start() {
this.emit("startup", "Start server...");
};
Server.prototype.__proto__ = EventEmitter.prototype;
现在Logger和Server彼此不认识。我可以重命名日志,我必须触摸的是Logger.js。我甚至可以删除Logger或添加更多Logger,所有这些都与Server一起使用。但我永远不必触及Server.js。
这是一个简单的例子,解耦在这里看起来并不重要。但是项目越大,获得的好处就越多。
您可以使用Unit-Test Server而无需模拟Logger。而Logger只是一个依赖。想象一下,如果服务器有五个或更多的子模块你必须模拟它的优势。
我希望这有助于您了解事件驱动架构的好处。