Nodejs 求助:emitter.setMaxListeners()

Nodejs 求助:emitter.setMaxListeners()

 (node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
at Socket.EventEmitter.addListener (events.js:168:15)
at Socket.EventEmitter.once (events.js:189:8)
at Socket.setTimeout (net.js:173:12)
at ClientRequest.setTimeout (http.js:1557:17)
at ClientRequest.setTimeout (http.js:1569:10)
at ClientRequest.g (events.js:185:14)
at ClientRequest.EventEmitter.emit (events.js:115:20)
at ClientRequest.onSocket (http.js:1514:9)
at process.startup.processNextTick.process._tickCallback (node.js:244:9)

使用request模块发送请求,当请求多的时候就出现这个警告,谁能告诉我一下应该在哪儿设置setMaxListeners(),我在自己的环境中没有调试出来。


4 回复

Node.js 求助:emitter.setMaxListeners()

当你在使用 Node.js 的 EventEmitter 时,如果添加了超过默认的最大监听器数量(默认为 10),你可能会看到如下的警告信息:

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.

这个警告提示你可能有内存泄漏的风险,因为你添加的监听器数量超过了默认限制。为了消除这个警告并增加最大监听器的数量,你可以使用 emitter.setMaxListeners() 方法。

示例代码

假设你在使用 request 模块来发送 HTTP 请求,并且遇到了上述警告。你可以在你的代码中显式地设置 setMaxListeners 方法来解决这个问题。

const request = require('request');
const EventEmitter = require('events');

// 创建一个 EventEmitter 实例
const myEmitter = new EventEmitter();

// 设置最大监听器数量为 20
myEmitter.setMaxListeners(20);

// 示例:使用 request 发送 HTTP 请求
request('http://example.com', (error, response, body) => {
    if (error) {
        console.error(error);
    } else {
        console.log(body);
    }
});

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

解释

  1. 创建 EventEmitter 实例

    const myEmitter = new EventEmitter();
    
  2. 设置最大监听器数量

    myEmitter.setMaxListeners(20);
    

    这行代码将最大监听器数量从默认的 10 增加到 20。

  3. 添加多个监听器

    for (let i = 0; i < 15; i++) {
        myEmitter.on(`event${i}`, () => {
            console.log(`Listener ${i} triggered`);
        });
    }
    

    在这个循环中,我们添加了 15 个监听器。由于我们已经设置了最大监听器数量为 20,所以不会触发警告。

通过这种方式,你可以避免因为监听器数量过多而引发的警告,从而确保你的 Node.js 应用程序更加健壮。


治标:

var req=http.request(options,function(res){
    //......
});
/** 此处为req.once,而非req.on,二者区别见官方文档api说明**/
req.once('socket',function(socket){
    /** 默认listener数是10,提高到20应该足够**/
    socket.setMaxListeners(20);
});

要治本,将timeout的回调函数独立出来,在response事件之后手动注销timeout的监听

var req=http.request(options,function(res){
    req.removeAllListeners();//clear out all listeners
    req.setTimeout(0,timeout_callback);//clear out timeout listener
    //do more work.......
});
function timeout_callback(){
    //abort request?......
}
/** for example, timeout in 30s**/
req.setTimeout(30000,timeout_callback);

PS: 记得node某个版本后clientrequest会自动注销监听,楼主的版本很旧?

非常感谢

当你使用 Node.js 的 EventEmitter 时,如果添加了超过默认的最大监听器数量(默认为 10 个),就会触发警告。在这个例子中,你已经添加了 11 个监听器,所以需要增加最大监听器的数量。

你可以通过调用 emitter.setMaxListeners(n) 方法来增加最大监听器的数量。这里的 n 是一个整数,表示允许的最大监听器数量。

示例代码:

const EventEmitter = require('events');
const myEmitter = new EventEmitter();

// 设置最大监听器数量为 15
myEmitter.setMaxListeners(15);

// 添加一些事件监听器
for (let i = 0; i < 15; i++) {
    myEmitter.on('event', () => {
        console.log('事件触发');
    });
}

在你的场景中,你可能需要在使用 request 模块时,在相应的 EventEmitter 实例上调用 setMaxListeners() 方法。例如:

const request = require('request');
const myEmitter = request('http://example.com');

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

// 添加事件监听器
myEmitter.on('response', (response) => {
    // 处理响应
});

// 添加更多事件监听器
myEmitter.on('data', (chunk) => {
    // 处理数据片段
});

请注意,你需要找到触发该警告的具体 EventEmitter 实例,并在该实例上设置 setMaxListeners()

回到顶部