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

如何用高效递归算法实现多层API数据拉取?

多层API数据拉取:递归实现的数组越界修复与优化方案

问题背景

需要调用6个API端点拉取服务器数据,构建层级化的响应树。初始实现采用大量嵌套for循环与if判断,代码冗余且难以维护。尝试递归重构时,出现endpoints数组越界问题,即使添加了长度校验也无法解决。

冗余的初始实现

async function fetch_children(endpoint, state) {
  const temp = await call_api(endpoint, state);
  state["children"] = await temp;
  state["endpoint"] = endpoint;
  return state;
}

async function loop_over(state) {
  const item = await fetch_children(endpoints[0], state);
  if (item["children"]) {
    for (const idx in item["children"]) {
      item["children"][idx] = await fetch_children(
        endpoints[1],
        item["children"][idx]
      );

      if (item["children"][idx]["children"]) {
        for (const idm in item["children"][idx]["children"]) {
          item["children"][idx]["children"][idm] = await fetch_children(
            endpoints[2],
            item["children"][idx]["children"][idm]
          );
          if (item["children"][idx]["children"][idm]["children"]) {
            for (const id in item["children"][idx]["children"][idm][
              "children"
            ]) {
              item["children"][idx]["children"][idm]["children"][id] =
                await fetch_children(
                  endpoints[3],
                  item["children"][idx]["children"][idm]["children"][id]
                );
              if (
                item["children"][idx]["children"][idm]["children"][id][
                  "children"
                ]
              ) {
                for (const idd in item["children"][idx]["children"][idm][
                  "children"
                ][id]["children"]) {
                  item["children"][idx]["children"][idm]["children"][id][
                    "children"
                  ][idd] = await fetch_children(
                    endpoints[5],
                    item["children"][idx]["children"][idm]["children"][id][
                      "children"
                    ][idd]
                  );
                }
              }
            }
          }
        }
      }
    }
  }
  return item;
}

存在问题的递归尝试

async function fetch_children(endpoint, state) {
  const temp = await call_api(endpoint, state);
  state["children"] = await temp;
  state["endpoint"] = endpoint;
  return state;
}

async function loop_over(endpoint, place) {
  const item = await fetch_children(endpoint, place);
  return item;
}

async function test(endpoints, state) {
  state = await loop_over(endpoints.pop(), state);
  if (state["children"].length >= 1 || endpoints.length >= 1) {
    for (const idx in state["children"]) {
      state["children"][idx] = await test(endpoints, state["children"][idx]);
    }
  }
  return state;
} 

问题根源

  1. 数组修改导致共享状态污染:使用endpoints.pop()会直接修改原数组,递归过程中所有子分支共享同一个数组实例,很快就会将数组元素取空,后续pop()会返回undefined,导致API调用传入无效端点。
  2. 条件判断逻辑错误:state["children"].length >=1 || endpoints.length >=1的逻辑不符合需求,应该是同时存在子节点和下一层端点时才需要递归。

预期响应树结构

{
  "name": "",
  "id": "",
  "children": [
    {
      "name": "",
      "id": "",
      "children": [
        {
          "name": "",
          "id": "",
          "children": [
            {
              "name": "",
              "id": "",
              "children": [
                { "name": "", "id": "" },
                { "name": "", "id": "" },
                { "name": "", "id": "" },
                { "name": "", "id": "" },
                { "name": "", "id": "" },
                { "name": "", "id": "" }
              ],
              "endpoint": "endpoints[3]"
            }
          ],
          "endpoint": "endpoints[2]"
        }
      ],
      "endpoint": "endpoints[1]"
    },
    {
        ....
    },
     ...
]

修复后的高效递归实现

核心优化点

  • 使用层级索引跟踪当前API端点,避免修改原数组
  • 用Promise.all并行处理子节点,提升拉取效率
  • 明确递归终止条件:层级超过端点数量或无子节点
async function fetch_children(endpoint, state) {
  const temp = await call_api(endpoint, state);
  state.children = temp;
  state.endpoint = endpoint;
  return state;
}

// 递归构建层级树
async function buildTree(endpoints, state, currentLevel = 0) {
  // 终止条件:当前层级超出端点列表长度,停止递归
  if (currentLevel >= endpoints.length) {
    return state;
  }

  const currentEndpoint = endpoints[currentLevel];
  // 调用当前层级的API,更新节点数据
  const updatedState = await fetch_children(currentEndpoint, state);

  // 若存在子节点,且还有下一层端点,并行递归处理所有子节点
  if (updatedState.children?.length && currentLevel + 1 < endpoints.length) {
    updatedState.children = await Promise.all(
      updatedState.children.map(child => buildTree(endpoints, child, currentLevel + 1))
    );
  }

  return updatedState;
}

// 调用示例:假设初始state是根节点数据,endpoints是6个API端点数组
// buildTree(endpoints, initialRootState).then(tree => console.log(tree));

代码说明

  1. 层级索引currentLevel:从0开始,每递归一层自增1,对应endpoints数组的下标,不会修改原数组,避免共享状态问题。
  2. 并行处理子节点:Promise.all同时发起所有子节点的API请求,相比串行循环大幅提升效率。
  3. 明确终止条件:当当前层级超过端点数量时,直接返回当前节点,不会继续递归。

内容的提问来源于stack exchange,提问作者eteturkist

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 23:47:42