NodeJS中的EventEmitters资源消耗殆尽吗?

时间:2018-05-23 02:59:17

标签: node.js

我想知道是否应该创建一个EventEmitter并将一个对象传递给它,其中将有一个键在回调函数中运行一些代码,具体取决于对象内部的键(我将有15种不同的情况)或者我应该根据15个不同的消息名称创建15个eventEmitters?我想知道创建多个evenEmitter是否会减慢,占用我的NodeJS实例的RAM或CPU资源

类似的东西:

 const EventEmitter = require('events');
 class MyEmitter extends EventEmitter {}
 const myEmitter = new MyEmitter();

 myEmitter.on('event1', (data) => console.log(data)); // receiver code
 myEmitter.on('event2', (data) => console.log(data)); //receiver code
 myEmitter.emit('event1','event1'); //sender code
 myEmitter.emit('event2','event2'); //sender code
//event3
//event4
//...

或类似的东西:

const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
let obj1 = { msgType:'event1',data:'one exemple'}; // sender code
let obj2 = { msgType:'event2',data:'another exemple'}; //sender code


myEmitter.on('event', (data) => { //receiver code

if (data.msgType=="event1"){
console.log("event1");
}
if (data.msgType=="event2"){
console.log("event2");
}

});

myEmitter.emit('event',obj1); //sender code
myEmitter.emit('event',obj2); //sender

1 个答案:

答案 0 :(得分:1)

所有事件发射器都只是一个Javascript对象,它保存包含各种方法的侦听器的数据结构。发射器中的非活动侦听器不占用CPU,只占用与存储回调引用和它正在侦听的消息名称一样多的RAM(因此,几乎没有RAM)。

您可以拥有尽可能多的发射器,对您的代码有意义。它们便宜又高效。您可以将它们视为静态的侦听器数组。当您执行.addListener()时,它会向数组添加一个项目。执行.removeListener()时,它会从数组中删除一个项目。执行.emit()时,它会找到与该特定消息匹配的侦听器并调用它们(只是函数调用)。

  

或者我应该创建15个eventEmitters,具体取决于15个不同的消息名称?

构建eventEmitter以处理许多不同的消息名称。因此,仅仅因为您有15条不同的消息,就没有理由制作15个独特的eventEmitter。您可以轻松地使用一个eventEmitter并使用所有不同的消息在其上调用.emit()

创建多个eventEmitters的原因与代码的设计和体系结构有关。如果你有一个组件,你想要模块化和可重用,并使用eventEmitter,那么它可能想要创建自己的发射器,并使其可用于其客户只是因此它不必有与其他代码也希望使用eventEmitter的依赖关系,但与此特定模块无关。因此,它是一个架构和代码组织问题,而不是运行时效率问题。只创建与您的架构一样多的eventEmitter,而不再需要它。

  

我想知道创建多个eventEmitter是否会减慢,占用我的NodeJS实例的RAM或CPU资源

不,它不会。每个eventEmitter只需要很少的内存就可以初始化它的基本实例数据,但这个数据很小,甚至可能无法测量1或其中15个和15个之间的差异。

  

我想知道是否应该创建一个EventEmitter并将一个对象传递给它,其中将有一个键在回调函数中运行一些代码,具体取决于对象内部的键。

如果您愿意,您可以自由地设计代码,但是您需要为自己做额外的工作并编写可能并非尽可能干净的代码。 eventEmitters的一大优势是它们为每个单独的消息维护一组特定的侦听器。如果您使用一条通用消息,然后将实际消息嵌入到传递给.emit()调用的对象中,那么您只是丢弃了eventEmitter所具有的功能,并对调用代码造成负担。在此事件中实际包含哪个子消息。

通常,这是使用EventEmitter的低效方式。相反,将实际事件名称放在.emit()中,并让代码注册一个侦听器,以获取它想要侦听的实际事件名称。

所以,在你展示的两种方案中,我非常喜欢第一种方案。这就是EventEmitters的设计使用方式以及它们如何帮助您。在某些情况下,您必须使用自己的子路由获得通用消息,但除非您确定需要这样,否则您不应该添加额外的复杂性并且丢弃EventEmitter的功能会为你免费做。

另外,您显示以下代码:

class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();

你是否意识到没有必要将EventEmitter子类化为使用它。如果您要在子类上添加或覆盖方法,则只能将其子类化。但是这段代码没有显示实际的新方法或覆盖,因此没有必要这样做。

如果您只想使用EventEmitter,只需创建一个:

const myEmitter = new EventEmitter();