递归函数无法正确返回Promise值:路由构建函数问题排查
问题分析与修复方案
你的代码核心问题出在异步递归的结果没正确传递,同步循环和异步操作不匹配,导致外层标记[*]的then块提前拿到undefined,直接返回了'no ticket'。具体问题点:
- 递归调用
getRoute后,仅在内部then里return结果,但这个return不会传递到外层Promise链,等于白处理了 while是同步循环,不会等待异步递归调用完成,会直接遍历完所有站点,外层then根本拿不到递归找到的有效结果- 找到终点时返回的Promise没被上层调用捕获,无法向上传递路径
修复后的代码
用async/await重构可以避免Promise嵌套的混乱,逻辑更清晰:
const solve = async (start, end, fetchRouts) => { // 记录已访问站点,避免循环访问(比如A→B→A的无限递归) const visited = new Set(); const getRoute = async (currentStation, stations) => { // 找到终点,直接返回路径 if (currentStation === end) { return stations; } // 已访问过的站点,跳过防止循环 if (visited.has(currentStation)) { return null; } visited.add(currentStation); // 等待获取下一站列表 const nextStations = await fetchRouts(currentStation); // 逐个遍历下一站,等待递归结果 for (const next of nextStations) { const result = await getRoute(next, [...stations, next]); // 找到有效路径立即返回,不再继续遍历 if (result) { return result; } } // 回溯移除标记(如果需要支持找多条路径,单路径场景可省略) visited.delete(currentStation); return null; }; const route = await getRoute(start, [start]); return route || 'no ticket'; };
关键改进点
- 用
async/await替代嵌套then,让异步逻辑像同步代码一样直观 - 新增
visited集合防止循环访问,避免无限递归 - 遍历下一站时,逐个等待递归结果,找到有效路径立即返回,不会无效遍历
- 递归函数直接返回路径数组或null,上层调用判断后返回最终结果,去掉了原代码里复杂的Promise包装对象
原代码的while循环换成for...of配合await,确保每个异步递归完成后再处理下一个站点,这样找到的路径能正确向上传递,不会出现外层提前返回'no ticket'的问题。
内容的提问来源于stack exchange,提问作者qbr_dude
相关产品推荐
相关产品推荐

