简体   繁体   English

在 Node.js 中,侦听 EventEmitter 是否会创建对它的引用?

[英]In Node.js, does listening to an EventEmitter, create a reference to it?

If I have some code like this:如果我有这样的代码:

const EventEmitter = require('events');

class Bot extends EventEmitter {
  sendMessage() {
    // do something
    this.emit('messageSent', 'user123');
  }
}

class Controller {
  loadBot() {
    const bot = new Bot();
    bot.on('messageSent', userId => {
      // do something
    });
  }
}

Would the bot object created inside loadBot be destroyed immediately?loadBot内部创建的bot对象会被立即销毁吗? or perhaps later via garbage collection?或者稍后通过垃圾收集?

Or would the instance of Controller hold a reference to it so that bot would never be destroyed until the Controller instance was destroyed?或者Controller的实例是否会持有对它的引用,以便在Controller实例被销毁之前bot永远不会被销毁?

Registering an event listener all by itself does not keep it from being garbage collected.单独注册一个事件侦听器并不能阻止它被垃圾收集。 Something has to actually have a reference to the Bot object itself (so that events could actually be emitted from it) for it to not be garbage collected.有些东西实际上必须有一个对Bot对象本身的引用(这样事件才能真正从它发出)才能不被垃圾收集。

In your Controller class, if nothing else has a reference to the Bot instance you create, then it will be eligible for garbage collection.在您的 Controller 类中,如果没有其他任何内容引用您创建的Bot实例,那么它将有资格进行垃圾回收。 This makes sense because if nothing has a reference to it, then nothing else can use it and nothing can ever call its custom method sendMessage() either.这是有道理的,因为如果没有任何东西可以引用它,那么其他任何东西都不能使用它,也没有任何东西可以调用其自定义方法sendMessage()

As you have your code now, your bot variable is just a local variable inside the loadBot() method and nothing else has a reference to it.正如您现在拥有的代码一样,您的bot变量只是loadBot()方法中的一个局部变量,没有其他任何东西可以引用它。 So, as soon as the loadBot() method is done executing, the bot variable will then be eligible for garbage collection because there is no code anywhere that could ever use or reach that object again.因此,一旦loadBot()方法执行loadBot()bot变量就可以进行垃圾回收,因为任何地方都没有代码可以再次使用或访问该对象。 That makes it eligible for garbage collection.这使它有资格进行垃圾收集。

From your code, it looks like maybe you meant for the bot variable to be an instance variable of your Controller object.从您的代码来看,您可能希望bot变量成为Controller对象的实例变量。 If that was the case, then as long as some had a reference to your Controller object, then the bot object would stay alive too.如果是这种情况,那么只要某些人引用了您的Controller对象,那么bot对象也会保持活动状态。

So, it looks like maybe you meant to do this:所以,看起来你可能打算这样做:

const EventEmitter = require('events');

class Bot extends EventEmitter {
  sendMessage() {
    // do something
    this.emit('messageSent', 'user123');
  }
}

class Controller {
  loadBot() {
    this.bot = new Bot();
    this.bot.on('messageSent', userId => {
      // do something
    });
  }

  send() {
      this.bot.sendMessage();
  }
}

var c = new Controller();
c.loadBot();

Here you retain a reference to the bot variable in the instance data of the Controller object and thus it can be reached by other code (like the send() method) or any other code that accesses the .bot property on your Controller object.在这里,您在Controller对象的实例数据中保留了对bot变量的引用,因此可以通过其他代码(如send()方法)或访问Controller对象上的.bot属性的任何其他代码访问它。

我不认为对象机器人会被垃圾回收,因为有一个监听器持有对它的引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM