如何使用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); }
问题分析
你的代码存在几个关键问题:
- 函数名拼写错误:
findOrganizations应为原代码中的findOrgs,名称不匹配导致调用失败。 - 返回值冗余:
organizationData返回包含单个对象的数组,后续map操作会导致嵌套数组,破坏数据结构。 - 未处理异步映射:
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
相关产品推荐
相关产品推荐

