SharePoint三级异步REST调用数据嵌套合并问题求助
核心问题梳理
当前代码存在两个关键问题:
- Promise链式调用失效:原代码中
getL1().then(()=>{getL2()})未返回getL2的Promise,导致后续then无法等待L2请求完成,也无法获取L2结果;同时依赖全局setL1、setL2传递ID集合,造成数据耦合且无法同步传递到合并函数。 - 空数组与匹配错误:按索引位置存储子任务的逻辑,在部分父任务无子女任务时生成空对象/数组,后续合并无法通过索引对应到正确父任务。
解决方案
1. 重构数据获取逻辑,移除全局变量
将ID集合的创建、传递放在函数内部,每个异步函数返回当前层级数据与子任务ID集合的组合,确保链式调用时能传递所有必要数据。
2. 通过ID关联实现嵌套合并
利用Map按parentID分组子任务,直接匹配父任务ID,自动处理无子女任务的场景,避免空数组问题。
完整实现代码
// 替换为实际SharePoint REST请求逻辑(sprLib调用) function fetchL1Tasks(targetOrg) { const taskL1 = [{"id":1,"title":"Task 1","org":"A"},{"id":2,"title":"Task 2","org":"B"},{"id":3,"title":"Task 3","org":"A"}]; return Promise.resolve(taskL1.filter(item => item.org === targetOrg)); } function fetchL2Tasks(parentIds) { const taskL2 = [{"id":20,"parentID":1},{"id":21,"parentID":1},{"id":22,"parentID":2},{"id":23,"parentID":2}]; return Promise.resolve(taskL2.filter(item => parentIds.has(item.parentID))); } function fetchL3Tasks(parentIds) { const taskL3 = [{"id":100,"parentID":20},{"id":111,"parentID":21},{"id":120,"parentID":22},{"id":220,"parentID":23}]; return Promise.resolve(taskL3.filter(item => parentIds.has(item.parentID))); } // 异步获取并合并三级任务 async function getMergedTasks(targetOrg) { // 1. 获取L1任务并收集ID集合 const l1Tasks = await fetchL1Tasks(targetOrg); const l1Ids = new Set(l1Tasks.map(task => task.id)); // 2. 获取L2任务并收集ID集合 const l2Tasks = await fetchL2Tasks(l1Ids); const l2Ids = new Set(l2Tasks.map(task => task.id)); // 3. 获取L3任务 const l3Tasks = await fetchL3Tasks(l2Ids); // 4. 按parentID分组子任务并嵌套 // 为L2绑定L3子任务 const l3Group = new Map(); l3Tasks.forEach(task => { l3Group.set(task.parentID, [...(l3Group.get(task.parentID) || []), task]); }); l2Tasks.forEach(task => { task.subtasks = l3Group.get(task.id) || []; }); // 为L1绑定L2子任务 const l2Group = new Map(); l2Tasks.forEach(task => { l2Group.set(task.parentID, [...(l2Group.get(task.parentID) || []), task]); }); l1Tasks.forEach(task => { task.subtasks = l2Group.get(task.id) || []; }); return l1Tasks; } // 调用示例 getMergedTasks('A').then(mergedData => { console.log(JSON.stringify(mergedData, null, 2)); }).catch(err => { console.error('请求或合并失败:', err); });
代码说明
- 无全局变量依赖:所有ID集合均在函数内部创建传递,避免异步数据冲突与全局污染。
- 异步逻辑清晰:使用
async/await替代嵌套then,确保每一步请求完成后再执行后续操作。 - 自动处理空任务:通过
Map分组匹配,无子女任务时自动赋值空数组,解决原代码中空对象/数组问题。 - 适配SharePoint环境:
fetchL1Tasks等函数可直接替换为sprLib的REST请求,只需保证返回Promise与对应数据结构即可。
内容的提问来源于stack exchange,提问作者Eric Smith
相关产品推荐
相关产品推荐

