如何在Node.js+mysql2中通过递归函数获取所有行及父行并返回结果?
问题分析与修复方案
你的代码存在几个核心问题,导致无法从函数返回结果:
- Promise未调用
resolve/reject,await永远等不到异步操作完成 - 递归调用
getLevel时未等待异步结果,递归流程没走完就提前结束 - 依赖全局
levels变量,函数本身未返回数据且易引发数据污染 - 数据库连接未正确释放,SQL语句存在注入风险
修复步骤
- 完善Promise处理:在异步操作完成(含递归结束)时调用
resolve返回结果,出错时调用reject抛出异常 - 递归等待异步结果:递归调用时加
await,确保父级等待子级查询完成 - 移除全局变量:在函数内部维护层级数组,避免多次调用时的数据污染
- 正确释放连接:查询完成后调用
connection.release()归还连接到池,不要直接关闭整个连接池 - 参数化查询防注入:改用
?占位符配合参数数组,避免SQL注入风险
修复后的完整代码
const mysql2 = require('mysql2') const pool = mysql2.createPool({ host: '127.0.0.1', user: 'root', password: '', database: 'dreamselling', waitForConnections: false, connectionLimit: 10, queueLimit: 0 }) const getLevel = async (id) => { const levels = []; // 内部递归查询函数 const fetchParent = async (currentId) => { return new Promise((resolve, reject) => { pool.getConnection((error, connection) => { if (error) return reject(error); // 参数化查询,避免SQL注入 const sql = 'select id,memberName,parent_id from member_table where id=?'; connection.query(sql, [currentId], (err, rows) => { connection.release(); // 查询完成后释放连接 if (err) return reject(err); if (!rows || rows.length === 0) return resolve(); const currentRow = rows[0]; levels.push(currentRow); // 存在父ID则继续递归查询 if (currentRow.parent_id !== null) { resolve(fetchParent(currentRow.parent_id)); } else { resolve(); } }); }); }); }; await fetchParent(id); return levels; } async function myfunc() { try { const result = await getLevel(7); console.log('层级数据:', result); return result; // 现在可以正常返回结果 } catch (err) { console.error('查询出错:', err); } } myfunc();
关键说明
- 用
async/await简化递归异步流程,代码逻辑更清晰 - 参数化查询彻底规避SQL注入风险
- 函数内部维护层级数组,避免全局变量污染
- 加入错误捕获,处理数据库查询或递归中的异常
内容的提问来源于stack exchange,提问作者Rahdartus
相关产品推荐
相关产品推荐

