如何通过递归API调用构建对象树?代码输出异常排查
递归构建对象树的问题排查与修复
问题描述
需要构建一棵对象树,从根节点开始,每个节点调用API获取其子节点,递归执行直到达到TREE_DEPTH_LIMIT(设置为3)。现有递归实现代码输出不符合预期,仅生成两层节点,而预期应包含三层节点。
现有代码
export const search = async (searchTerm) => { try { const tree = {}; await createTree(searchTerm, tree); return tree; } catch (err: any) {} }; const TREE_DEPTH_LIMIT = 3; const createTree = async (searchTerm, tree) => { if (counter === TREE_DEPTH_LIMIT) { counter = 0; return; } counter++; tree[searchTerm] = {}; try { const res = await axiosInstance.get( `/query?term=${searchTerm}` ); // res.data.terms is an array of strings res.data.terms.forEach((term) => { createTree(term, tree[searchTerm]); }); } catch (err) {} };
实际输出
const tree = { apple: { apple_tree: {}, tree: {}, }, };
预期输出
const tree = { apple: { apple_tree: { leaf: {}, }, tree: { trunk: {}, }, }, };
问题分析与修复
原方案并非完全错误,核心问题出在全局计数器干扰和异步调用未等待两个点:
- 全局counter的问题:代码中未声明的全局
counter会被所有递归分支共享,当多个子节点同时递归时,counter值会被混乱修改,导致部分递归提前终止,无法生成完整层级。 - 异步调用未等待:
forEach循环中调用异步的createTree,但forEach不会等待Promise完成,外层函数会提前返回,导致子节点的递归还未执行完就结束,最终只生成两层节点。
修复后的代码
export const search = async (searchTerm) => { try { const tree = {}; // 初始调用时传入当前深度为0 await createTree(searchTerm, tree, 0); return tree; } catch (err) { console.error('构建树失败:', err); throw err; } }; const TREE_DEPTH_LIMIT = 3; const createTree = async (searchTerm, tree, currentDepth) => { // 当前深度达到限制时停止递归 if (currentDepth >= TREE_DEPTH_LIMIT) { return; } tree[searchTerm] = {}; const currentNode = tree[searchTerm]; try { const res = await axiosInstance.get(`/query?term=${searchTerm}`); // 用Promise.all等待所有子节点的递归异步操作完成 await Promise.all(res.data.terms.map(term => { return createTree(term, currentNode, currentDepth + 1); })); } catch (err) { console.error(`获取${searchTerm}的子节点失败:`, err); } };
修复说明
- 用参数传递深度:替换全局
counter为currentDepth参数,每个递归分支独立维护自身深度,避免分支间互相干扰。 - 等待异步递归完成:将
forEach改为map+Promise.all,确保所有子节点的递归异步操作都执行完成后,当前函数才返回,保证树的层级完整。 - 深度逻辑调整:初始深度设为0,递归时递增,当
currentDepth >= TREE_DEPTH_LIMIT时停止,刚好生成3层节点(0→第1层,1→第2层,2→第3层)。
内容的提问来源于stack exchange,提问作者webber
相关产品推荐
相关产品推荐

