在 Node.js 中,是否监听 EventEmitter,创建对它的引用?
In Node.js, does listening to an EventEmitter, create a reference to it?
如果我有这样的代码:
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
});
}
}
在loadBot
中创建的bot
对象会立即销毁吗?或者稍后通过垃圾收集?
或者 Controller
的实例是否会保留对它的引用,以便 bot
在 Controller
实例被销毁之前永远不会被销毁?
单独注册一个事件侦听器并不能阻止它被垃圾收集。某些东西实际上必须有对 Bot
对象本身的引用(以便事件实际上可以从它发出)才能不被垃圾收集。
在您的控制器 class 中,如果没有其他对象引用您创建的 Bot
实例,那么它将有资格进行垃圾回收。这是有道理的,因为如果没有任何东西引用它,那么就没有其他东西可以使用它,也没有任何东西可以调用它的自定义方法 sendMessage()
。
正如您现在的代码,您的 bot
变量只是 loadBot()
方法中的一个局部变量,没有其他任何东西引用它。因此,一旦 loadBot()
方法执行完毕,bot
变量就可以进行垃圾回收,因为任何地方都没有代码可以再次使用或访问该对象。这使得它有资格进行垃圾收集。
从您的代码来看,您的意思可能是 bot
变量是 Controller
对象的实例变量。如果是这样,那么只要有人引用了您的 Controller
对象,那么 bot
对象也会保持活动状态。
所以,看起来你可能打算这样做:
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();
此处您在 Controller
对象的实例数据中保留了对 bot
变量的引用,因此它可以被其他代码访问(如 send()
方法)或访问 Controller
对象上的 .bot
属性 的任何其他代码。
我不认为对象 bot 会被 GC,因为有一个侦听器持有对它的引用。
如果我有这样的代码:
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
});
}
}
在loadBot
中创建的bot
对象会立即销毁吗?或者稍后通过垃圾收集?
或者 Controller
的实例是否会保留对它的引用,以便 bot
在 Controller
实例被销毁之前永远不会被销毁?
单独注册一个事件侦听器并不能阻止它被垃圾收集。某些东西实际上必须有对 Bot
对象本身的引用(以便事件实际上可以从它发出)才能不被垃圾收集。
在您的控制器 class 中,如果没有其他对象引用您创建的 Bot
实例,那么它将有资格进行垃圾回收。这是有道理的,因为如果没有任何东西引用它,那么就没有其他东西可以使用它,也没有任何东西可以调用它的自定义方法 sendMessage()
。
正如您现在的代码,您的 bot
变量只是 loadBot()
方法中的一个局部变量,没有其他任何东西引用它。因此,一旦 loadBot()
方法执行完毕,bot
变量就可以进行垃圾回收,因为任何地方都没有代码可以再次使用或访问该对象。这使得它有资格进行垃圾收集。
从您的代码来看,您的意思可能是 bot
变量是 Controller
对象的实例变量。如果是这样,那么只要有人引用了您的 Controller
对象,那么 bot
对象也会保持活动状态。
所以,看起来你可能打算这样做:
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();
此处您在 Controller
对象的实例数据中保留了对 bot
变量的引用,因此它可以被其他代码访问(如 send()
方法)或访问 Controller
对象上的 .bot
属性 的任何其他代码。
我不认为对象 bot 会被 GC,因为有一个侦听器持有对它的引用。