递归遍历Promise:REST API层级分组数据获取问题
递归遍历Promise获取所有层级分组的解决方案
嘿,这个问题我之前做权限系统的时候刚好碰到过!你的API只能返回当前分组的直接子级,要拿到全量的嵌套结构,用递归结合async/await + Promise.all就能轻松搞定,我给你一步步拆解:
核心思路
- 先写一个基础函数调用你的API,获取当前分组的直接子分组;
- 写一个递归函数:拿到当前分组的子分组后,对每个子分组重复调用这个递归函数,获取它们的子级;
- 用
Promise.all并行处理所有子分组的异步请求,等所有子级都获取完后,组装成嵌套结构返回。
代码示例
1. 模拟你的API调用函数
先写个模拟函数代替你的真实API,实际使用时替换成你自己的请求逻辑(比如fetch或axios):
// 模拟API:传入分组名称,返回该分组的直接子分组Promise function fetchChildGroups(groupName) { // 这里模拟你的API返回逻辑,实际替换成真实请求 const groupData = { "Group 1": ["Group A", "Group B"], "Group A": ["Group X"], "Group B": [], "Group X": [] }; // 模拟网络延迟 return new Promise(resolve => { setTimeout(() => resolve(groupData[groupName] || []), 100); }); }
2. 递归获取全部分组的核心函数
用async/await让异步递归逻辑更清晰:
async function fetchAllGroups(rootGroupName) { // 第一步:获取当前分组的直接子分组 const directChildren = await fetchChildGroups(rootGroupName); // 第二步:对每个子分组递归调用,获取它们的所有子级 // 用Promise.all并行处理,提升请求效率 const nestedChildren = await Promise.all( directChildren.map(async childName => { // 递归获取子分组的全量数据 const childSubGroups = await fetchAllGroups(childName); // 组装成嵌套结构,你可以根据需求调整格式 return { name: childName, children: childSubGroups }; }) ); return nestedChildren; }
3. 使用示例
// 调用函数获取"Group 1"的所有层级分组 fetchAllGroups("Group 1") .then(allGroups => { console.log("全量嵌套分组:", JSON.stringify(allGroups, null, 2)); }) .catch(error => { console.error("获取分组失败:", error); });
运行后会输出这样的嵌套结构:
[ { "name": "Group A", "children": [ { "name": "Group X", "children": [] } ] }, { "name": "Group B", "children": [] } ]
实用优化建议
错误处理
如果API可能请求失败,建议在fetchChildGroups里添加错误捕获,或者在递归函数里处理,避免单个请求失败导致整个递归链崩溃:
async function fetchChildGroups(groupName) { try { // 真实API请求逻辑 const response = await fetch(`/api/groups/${encodeURIComponent(groupName)}`); if (!response.ok) throw new Error(`请求失败:${response.status}`); return await response.json(); } catch (err) { console.error(`获取${groupName}的子分组失败:`, err); return []; // 失败时返回空数组,不中断递归 } }
缓存优化
如果同一个分组可能被多次请求(比如不同父分组下有同名子分组),可以加个缓存避免重复调用API:
const groupCache = new Map(); // 缓存已获取的分组数据 async function fetchAllGroups(rootGroupName) { // 先查缓存,有直接返回 if (groupCache.has(rootGroupName)) { return groupCache.get(rootGroupName); } const directChildren = await fetchChildGroups(rootGroupName); const nestedChildren = await Promise.all( directChildren.map(async childName => { const childSubGroups = await fetchAllGroups(childName); return { name: childName, children: childSubGroups }; }) ); // 存入缓存 groupCache.set(rootGroupName, nestedChildren); return nestedChildren; }
请求限流(可选)
如果API有请求频率限制,把Promise.all改成串行处理(比如用for...of循环),避免触发限流:
async function fetchAllGroups(rootGroupName) { const directChildren = await fetchChildGroups(rootGroupName); const nestedChildren = []; // 串行处理每个子分组的请求 for (const childName of directChildren) { const childSubGroups = await fetchAllGroups(childName); nestedChildren.push({ name: childName, children: childSubGroups }); } return nestedChildren; }
这样就能自动遍历所有层级的分组啦,你可以根据自己的业务需求调整返回的结构格式~
内容的提问来源于stack exchange,提问作者user5417542
相关产品推荐
相关产品推荐

