NodeJS递归数据库查询函数开发问题:仅遍历2层且终止逻辑异常
Node.js递归查询数据库的问题修复
问题背景
需要开发一个Node.js递归函数,查询数据库后基于结果反复调用自身,直到所有批次编号都无法再分解为止。例如:传入001返回002、003、004;002可分解为002-A、002-B、002-C,其中前两个还能继续分解,003、004、002-C无法分解。核心需求是遍历所有层级,不能中途停止。
现有代码存在两个问题:
- 仅递归2层就停止迭代
- 终止条件逻辑错误,若某一批次无查询结果会中途停止,忽略其他还能分解的批次
问题根源分析
- 全局变量污染:
lotArray和resultArray是全局变量,每次递归都会复用,导致数据混乱,递归逻辑无法正确推进 - 异步流程未正确链式处理:第一次调用后的递归未用
.then或await处理,后续递归无法正常执行 - 终止判断缺失:没有逐个处理每个批次的递归,也未判断当前批次是否还有可分解的结果
修复后的代码
// 封装单个批次查询,复用数据库连接 async function querySingleLot(sqlConn, lotNumber) { try { const result = await sqlConn.query(`SELECT mt.lot AS [MatlLot] from lot mt WHERE job_lot = '${lotNumber}'`); return result.recordset; } catch (err) { console.error(`查询批次${lotNumber}出错:`, err); return []; } } // 递归遍历所有层级批次的核心函数 async function traverseAllLots(startLot, sqlConn) { let allLots = []; // 查询当前批次的子批次 const childLots = await querySingleLot(sqlConn, startLot); allLots.push(...childLots); // 逐个递归处理每个子批次,收集所有层级结果 for (const child of childLots) { const grandChildLots = await traverseAllLots(child.MatlLot, sqlConn); allLots.push(...grandChildLots); } return allLots; } // 主执行入口 async function main() { let sqlConn; try { // 仅建立一次数据库连接,避免重复连接开销 sqlConn = await sql.connect(config); const startLot = "A2400"; const allResultLots = await traverseAllLots(startLot, sqlConn); console.log('所有层级的批次结果:', allResultLots); } catch (err) { console.error('全局错误:', err); } finally { // 确保数据库连接关闭,避免泄漏 if (sqlConn) { await sqlConn.close(); } } } // 启动执行 main();
关键优化点
- 移除全局变量:所有数据通过函数参数和返回值传递,避免数据污染
- 复用数据库连接:仅建立一次连接,递归过程复用,提升性能
- 异步递归处理:用
await确保每个递归调用完成后再继续,遍历所有层级 - 独立批次处理:对每个子批次单独递归,不会因某一批次无结果影响其他批次
- 错误隔离:单个批次查询出错不中断整体流程,同时打印具体错误便于排查
内容的提问来源于stack exchange,提问作者Sreenath Umagandhi
相关产品推荐
相关产品推荐

