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

递归调用MS Graph API的DFS函数为何无法等待异步执行完成

问题根因

现有代码无法直接拿到结果的核心原因是异步逻辑没有被正确等待:

  • start是同步函数,内部发起的callMsGraph异步请求、递归调用都没有被阻塞,函数会在所有请求发出后立刻返回空数组,此时数组还没被异步回调填充
  • 遍历用的forEach不支持异步等待,即使回调内写了Promise逻辑,外层也不会等待回调执行完成
  • 递归调用start时没有返回/等待对应的Promise,外层完全无法感知递归内部的异步执行状态,只能靠固定时长的setTimeout碰运气等请求跑完。
修复后完整代码

callMsGraph工具函数不需要修改,只需要调整shelfdb.data内的递归逻辑即可:

shelfdb.data = async (accessToken) => {

    const token = accessToken;
    const endpoint = 'https://graph.microsoft.com/v1.0/sites/webgroup.sharepoint.com,23e7ef7a-a529-4dde-81ba-67afb4f44401,0fa8e0f7-1c76-4ad0-9b6e-a485f9bfd63c/drive/items/01GNYB5KPQ57RHLPZCJFE2QMVKT5U3NYY3/children'
    
    async function start(node, array) {
        if(node.value?.length > 0) {
            for (const child of node.value) {
                const end = 'https://graph.microsoft.com/v1.0/sites/webgroup.sharepoint.com,23e7ef7a-a529-4dde-81ba-67afb4f44401,0fa8e0f7-1c76-4ad0-9b6e-a485f9bfd63c/drive/items/' + child.id + '/children';
                try {
                    const currResult = await callMsGraph(token, end);
                    if (currResult.value?.length > 0) {
                        if ('image' in currResult.value[0]) {
                            currResult.value.forEach(function(imgChild) {
                                let img = {
                                    'name': imgChild.name,
                                    'job': imgChild.parentReference.path.split("/")[6],
                                    'path': imgChild.webUrl,
                                    'id': imgChild.id
                                }
                                array.push(img);
                            })
                            continue;
                        }
                        await start(currResult, array);
                    }
                } catch (e) {
                    console.error(e.message);
                }
            }
        }
        return array;
    }
    
    const res = await callMsGraph(token, endpoint);
    const output = await start(res, []); 
    console.log(output);
    return output;
}
关键修改说明
  • 将start改为async函数,允许内部通过await阻塞异步流程
  • 替换原forEach循环为for...of循环:forEach不会等待异步回调执行,for...of配合await可以保证当前节点的请求、子节点递归全部执行完成后,再处理下一个同级节点,符合深度优先搜索的执行顺序
  • 所有异步操作(接口请求、递归调用)都添加await,让整个异步执行链的状态可以被外层捕获,不会提前返回空数组
  • 增加可选链?.判断,避免接口返回异常结构时抛出Cannot read properties of undefined错误
  • 错误处理移入循环内部,单个节点请求失败不会中断整个遍历流程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:45:39