gpt4 book ai didi

javascript - 如何解决nodejs uncaughtException : Connection already released error and MaxListenersExceededWarning?

转载 作者:行者123 更新时间:2023-12-01 13:10:02 25 4
gpt4 key购买 nike

我正在构建一个快速服务器来接收来自我的 react 前端的请求(一个包含 10 个项目的字典),然后将数据保存到数据库中。下面是我的代码。我发现我的代码有效,并且查询确实将记录保存回 Db。但是在每个 for 循环中,服务器都会返回此错误。是什么导致此错误和 MaxListenersExceededWarning?

The request data: 
{{.....}, {.....}, {.....}, {.....}, {.....}} #10 item

Code:
connection.js:
const p = mysql.createPool({
"connectionLimit" : 100,
"host": "example.org",
"user": "test",
"password": "test",
"database": "test",
"multipleStatements": true
});

const getConnection = function(callback) {
p.getConnection(function(err, connection) {
callback(err, connection)
})
};

module.exports = getConnection

routers.js
router.post('/test', (req, res) => {
getConnection(function(err, conn){
if (err) {
return res.json({ success: false, error: err })
} else {
const dict = req.body;
Object.keys(dict).forEach(function(r){
#putting dict's value to query
query = "UPDATE ......;"
conn.query(query, function (err, result, fields) {
conn.release()
console.log(query)
if (err) {
console.log("err")
return res.json({ success: false, error: err });
}
});
});
}
});
return res.json({ success: true });
});

Error:
error: uncaughtException: Connection already released
Error: Connection already released
at Pool.releaseConnection (/home/node_modules/mysql/lib/Pool.js:138:13)
at PoolConnection.release (/home/node_modules/mysql/lib/PoolConnection.js:35:15)
at Query.<anonymous> (/home/routes/test.js:276:22)
at Query.<anonymous> (/home/node_modules/mysql/lib/Connection.js:526:10)
at Query._callback (/home/node_modules/mysql/lib/Connection.js:488:16)
at Query.Sequence.end (/home/node_modules/mysql/lib/protocol/sequences/Sequence.js:83:24)
at Query._handleFinalResultPacket (/home//node_modules/mysql/lib/protocol/sequences/Query.js:149:8)
at Query.OkPacket (/home//node_modules/mysql/lib/protocol/sequences/Query.js:74:10)
at Protocol._parsePacket (/home//node_modules/mysql/lib/protocol/Protocol.js:291:23)
at Parser._parsePacket (/home//node_modules/mysql/lib/protocol/Parser.js:433:10)
(node:15881) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 finish listeners added. Use emitter.setMaxListeners() to increase limit

最佳答案

正在从池中检索一个连接 (conn),用于在 forEach 中启动 10 个查询。环形。

当第一个查询完成运行时,其回调的第一步是:conn.release() .连接被释放。

当第二个查询完成运行时,它的回调也尝试释放连接,从而导致错误。

这个问题可以通过多种方式解决:

使用计数器解决

在数据库查询的回调中,调用call.release之前,检查已处理的查询数,仅在处理最后一个产品时关闭连接。

      const dict = req.body;

// initialize counter
let itemCount = 0
, errors = []

Object.keys(dict).forEach(function(r){
#putting dict's value to query
query = "UPDATE ......;"
conn.query(query, function (err, result, fields) {


// check whether this is the last callback
if (itemCount === dict.length-1) {
conn.release()

let result = errors.length ? { success: false, error: errors } : { success: true }

res.json(result)

}

// increment counter
itemCount++

console.log(query)
if (err) {
console.log("err")
errors.push(err)
}
});
});

编辑 : res.json 还有一个问题调用:在问题的代码中, res.json({ success: true })始终执行,无需等待查询的执行结果。上面修改后的代码示例调用 res.json在所有查询执行后只有一次,这是唯一的地方 res.json应该调用。这意味着修改客户端代码,以便它可以处理一系列错误,而不仅仅是一个错误。

通过使用递归函数而不是 for 循环来解决。

使用 for 不是一个好习惯用于执行异步代码的循环。你可能会遇到 Maximum call stack size exceeded数据量太大时出错。

相反,创建一个递归函数(例如 updateDictItem )来一次处理一个更新查询。阅读 this article 中有关 node.js 中的异步模式的更多信息.

其他可能的增强功能

与其触发十个数据库查询,不如考虑将所有更新分组到一个 MERGE update statement ,否则在 TRANSACTION 中进行所有更新.

关于javascript - 如何解决nodejs uncaughtException : Connection already released error and MaxListenersExceededWarning?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60692115/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com