Nodejs emitter.setMaxListeners()的问题

Nodejs emitter.setMaxListeners()的问题

我的node版本是最新版本。而且,没有使用event。只是简单的刷新列表页面,出现 warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit. data: Trace data: at Socket.EventEmitter.addListener (events.js:160:15) data: at Socket.Readable.on (_stream_readable.js:653:33) data: at Socket.EventEmitter.once (events.js:179:8) data: at TCP.onread (net.js:527:26)


7 回复

Nodejs emitter.setMaxListeners() 的问题

问题描述

在使用 Node.js 处理某些事件时,你可能会遇到以下警告信息:

warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
data:    Trace
data:        at Socket.EventEmitter.addListener (events.js:160:15)
data:        at Socket.Readable.on (_stream_readable.js:653:33)
data:        at Socket.EventEmitter.once (events.js:179:8)
data:        at TCP.onread (net.js:527:26)

这条警告信息表示你已经添加了超过默认的最大监听器数量(默认为10个)。如果你的代码中并没有显式地使用 EventEmitter,但仍然出现了这个问题,可能是由于某些内部机制或第三方库触发了这些事件。

解决方案

你可以通过调用 emitter.setMaxListeners(n) 方法来增加最大监听器的数量。这里 n 是一个整数,表示你希望设置的最大监听器数量。如果 n 设置为 0 或者 Infinity,则表示取消限制。

示例代码

假设你有一个简单的 HTTP 服务器,当接收到请求时,它会监听一些事件。你可以通过如下方式解决这个问题:

const http = require('http');

// 创建一个 HTTP 服务器
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('Hello World\n');
});

// 增加最大监听器数量
server.setMaxListeners(15); // 设置为 15 个

// 监听连接事件
server.on('connection', (socket) => {
  console.log('New connection established.');
  
  // 监听数据事件
  socket.on('data', (chunk) => {
    console.log(`Received data: ${chunk}`);
  });

  // 监听结束事件
  socket.on('end', () => {
    console.log('Connection closed.');
  });
});

// 监听端口
server.listen(3000, () => {
  console.log('Server is listening on port 3000');
});

在这个例子中,我们创建了一个 HTTP 服务器,并设置了最大监听器数量为 15。这样可以避免由于事件监听器过多而引发的警告信息。

总结

  • 使用 emitter.setMaxListeners(n) 可以增加最大监听器的数量。
  • 如果你的应用中有很多事件监听器,建议适当调整这个值,以避免内存泄漏的风险。
  • 注意不要将最大监听器数量设置得过高,否则可能会导致不必要的资源消耗。

问题的根源是在同一个对象上注册过多的监听函数,例如on(<event>,<callback>)这种调用。由于半点相关代码都没贴出来,偶也只能给出一些笼统的提示: 刷新列表对应的函数里面,是否依赖于外部某些对象,是否一直通过on函数注册监听,有没有在适当的地方通过removeAllListeners注销监听。

问题比较隐蔽,相对于明显的 on函数,我更多的使用 callback 这种调用,根据你的回复,我得检查一下,消息队列的监听 是不是有不合理的地方。

哪有。。我把所有的监听函数都去掉了,用的callback回调。。还是会有这种情况发生。。

既然如此肯定自己的代码没问题,那么就把触发这个警告信息的socket揪出来,setMaxListeners(0)来绕过此警告吧。

PS:callback也有可能与事件监听挂钩的,event是nodejs的核心之一,事件的监听是不可避免的。

当你在Node.js中遇到EventEmitter警告提示可能的内存泄漏时(如11个监听器已添加),这通常是因为默认情况下,EventEmitter最多允许10个监听器。如果你添加了更多的监听器,Node.js会发出警告。

解决这个问题的方法是使用emitter.setMaxListeners()方法来增加允许的最大监听器数量。下面是一个简单的例子来说明如何使用这个方法:

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {
}

const myEmitter = new MyEmitter();

// 增加最大监听器数量到15
myEmitter.setMaxListeners(15);

myEmitter.on('event', () => {
    console.log('Event triggered!');
});

// 添加更多监听器
for (let i = 0; i < 14; i++) {
    myEmitter.on('event', () => {
        console.log(`Listener ${i + 1}`);
    });
}

在这个例子中,我们首先创建了一个继承自EventEmitter的类MyEmitter。然后我们创建了一个实例myEmitter,并通过调用setMaxListeners(15)方法将最大监听器数量设置为15。这样,即使添加超过10个监听器也不会再触发警告。

如果你不确定为什么会出现如此多的监听器,还需要检查你的代码逻辑,确保没有不必要的监听器被重复添加。

回到顶部