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

如何使用Promise.all实现orgsData函数的并行递归版本?

问题描述

服务器存储的组织层级数据结构如下:

[
  { id: 1, name: 'org_1', parent_id: 0 },
  { id: 2, name: 'org_2', parent_id: 0 },
  { id: 3, name: 'dep_1', parent_id: 1 },
  { id: 4, name: 'dep_2', parent_id: 1 },
  { id: 5, name: 'dep_1', parent_id: 2 },
  // ...更多数据
]

现有串行递归获取数据的代码:

const fetchData = async (params) => {
  const url = new URL(REMOTE_APP_HOST);
  url.search = new URLSearchParams(params).toString();

  const response = await fetch(url, {
    credentials: "include",
    headers: new Headers({
      Authorization: "Basic " + API_ACCOUNT,
      "Content-Type": "application/json",
    }),
  });
  return await response.json();
};

const findOrgs = async (parent_id) => {
  const params = {
    parent_id: parent_id,
  };

  try {
    return await fetchData(params);
  } catch (err) {
    console.log("findOrgs, fetch error: ", err);
  }
};

const orgsData = async (parent_id) => {
  const data = []
 
  const organizations = await findOrgs(parent_id);

  for (const organization of organizations) {
    const organizationData = {
      name: organization.name,
      type: "organization",
      children: [],
    };

    organizationData.children = await orgsData(
      organization.id
    );

    data.push(organizationData);
  }

  return data
};

const orgsList = async () => {
  return await orgsData(0);
};

其中orgsData通过串行递归方式获取子组织数据,现在需要改成并行版本用Promise.all优化性能,但自行编写的代码无法正常运行:

const organizationData = async (organization) => {
  const data = [];

  const orgData = {
    name: organization.name,
    type: "organization",
    children: [],
  };

  const subOrgs = await orgsData_2(organization.id);
  orgData.children = subOrgs.map(organizationData);

  data.push(orgData);

  return data;
}

const orgsData_2 = async (parent_id) => {
  
  const organizations = await findOrganizations(parent_id);

  const promises = organizations.map(organizationData);

  return await Promise.all(promises);
}

问题分析

你的代码存在几个关键问题:

  1. 函数名拼写错误:findOrganizations应为原代码中的findOrgs,名称不匹配导致调用失败。
  2. 返回值冗余:organizationData返回包含单个对象的数组,后续map操作会导致嵌套数组,破坏数据结构。
  3. 未处理异步映射:subOrgs.map(organizationData)返回的是Promise数组,未用await Promise.all()等待兑现,导致children存储的是未完成的Promise而非实际数据。

正确的并行实现代码
// 处理单个组织及其子组织的异步函数
const processOrg = async (organization) => {
  const orgItem = {
    name: organization.name,
    type: "organization",
    children: []
  };
  // 递归并行获取子组织
  orgItem.children = await orgsDataParallel(organization.id);
  return orgItem;
};

// 并行版组织数据获取函数
const orgsDataParallel = async (parent_id) => {
  const organizations = await findOrgs(parent_id);
  if (!organizations) return []; // 处理接口返回空或异常的情况
  
  // 并行处理所有同级组织
  const orgPromises = organizations.map(processOrg);
  return await Promise.all(orgPromises);
};

// 入口函数
const orgsListParallel = async () => {
  return await orgsDataParallel(0);
};

优化说明
  • 同级并行处理:用organizations.map(processOrg)生成所有同级组织的处理Promise,通过Promise.all()等待全部完成,替代原串行for...of循环,大幅提升同级组织的获取效率。
  • 递归保持并行性:processOrg内部调用orgsDataParallel,让每个子层级的组织也以并行方式获取,整个递归流程中所有同级请求都是并发的。
  • 兼容错误处理:保留原findOrgs的错误捕获逻辑,单个请求失败不会阻断整个流程(若需严格失败控制,可在orgsDataParallel中添加try/catch)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 00:15:44