Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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? 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?

like image 349
abc123 Avatar asked Mar 12 '23 16:03

abc123


1 Answers

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.

In your Controller class, if nothing else has a reference to the Bot instance you create, then it will be eligible for garbage collection. 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.

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. 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. 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. 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.

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.

like image 126
jfriend00 Avatar answered Apr 24 '23 22:04

jfriend00