Node.js中MySQL包多请求返回问题及连接池使用咨询
问题修复与连接池说明
一、修复gather_info函数及路由的问题
你的代码存在三个核心问题:
- 异步操作未等待完成:三个
sql.query都是异步执行的,原代码直接在查询未结束时调用callback,导致返回的info是空数组。 - 变量名错误:路由中
admins: users.admins应为admins: info.admins。 - 响应重复发送:
if块未加拦截逻辑,导致管理员用户会触发两次响应(res.render('admin')和后续的res.render('index')),引发错误。
修复后的代码
首先确保使用支持Promise的MySQL库(推荐mysql2/promise,原生支持Promise),然后改造代码如下:
1. 改造gather_info为异步函数
async function gather_info() { const info = { users: [], admins: [], events: [] }; // 并行执行三个查询,提升效率 const [usersResult, adminsResult, eventsResult] = await Promise.all([ sql.query("SELECT * FROM users"), sql.query("SELECT * FROM users WHERE isAdmin = 1"), sql.query("SELECT * FROM events") ]); // mysql2的query返回[查询结果, 字段元数据],取第一个元素即可 info.users = usersResult[0]; info.admins = adminsResult[0]; info.events = eventsResult[0]; return info; }
2. 修复路由逻辑
app.get("/", loginRequired, async (req, res, next) => { if (req.user.isAdmin) { try { const info = await gather_info(); return res.render('admin', { events: info.events, users: info.users, admins: info.admins }); } catch (err) { // 传递错误给Express错误处理中间件 return next(err); } } // 非管理员用户逻辑 try { const [events] = await sql.query("select * from events where userId = ?", [req.user.ID]); res.render("index", { events }); } catch (err) { next(err); } });
修复说明
- 用
async/await处理异步流程,确保所有查询完成后再返回数据。 Promise.all并行执行三个查询,比串行执行更高效。- 修复变量名错误,避免渲染页面时数据缺失。
- 添加
return和错误捕获,防止重复响应及未处理的错误导致服务器崩溃。
二、连接池是否需要关闭连接?
不需要手动关闭连接,原因如下:
- 使用
createPool创建的连接池会自动管理连接的生命周期:调用pool.query()时,池会自动分配可用连接,执行完查询后自动将连接放回池内复用。 - 只有当你手动调用
pool.getConnection()获取单个连接时,才需要在使用完毕后调用connection.release()将连接归还池,否则会导致连接池耗尽,无法处理新请求。
内容的提问来源于stack exchange,提问作者Ritalin
相关产品推荐
相关产品推荐

