You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过递归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: {},
    },
  },
};

问题分析与修复

原方案并非完全错误,核心问题出在全局计数器干扰和异步调用未等待两个点:

  1. 全局counter的问题:代码中未声明的全局counter会被所有递归分支共享,当多个子节点同时递归时,counter值会被混乱修改,导致部分递归提前终止,无法生成完整层级。
  2. 异步调用未等待: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:55:25