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

JS递归函数未执行完时return为何提前返回空images数组

问题根因

返回值为空是典型的异步逻辑未等待导致的:

  • callMsGraph是返回Promise的异步函数,所有API请求的回调逻辑都会进入JS事件队列排队,不会阻塞同步代码执行
  • 现有代码执行到return images时,res.then()触发的遍历逻辑、start函数内所有递归的Graph API请求都还没执行到images.push()的步骤,此时返回的只是初始化的空数组
  • 你在start内部的console.log能看到数据,是因为这些日志在异步回调里执行,时机晚于函数return,和你拿到的返回值不是同一个时间点的状态
  • 原代码没有对递归、循环里的多个异步Promise做聚合等待,外层根本无法获知遍历什么时候完成
修复方案

把整个流程改成async/await写法,所有异步操作全部等待完成后再返回结果,修复后代码如下:

shelfdb.data = async (accessToken) => {
    const token = accessToken;
    const rootEndpoint = 'https://graph.microsoft.com/v1.0/sites/webgroup.sharepoint.com,23e7ef7a-a529-4dde-81ba-67afb4f44401,0fa8e0f7-1c76-4ad0-9b6e-a485f9bfd63c/drive/items/01GNYB5KPQ57RHLPZCJFE2QMVKT5U3NYY3/children'
    const images = [];

    async function start(node) {
        if (!node.value) return;
        // 等待当前层级所有子节点请求、递归遍历全部完成
        await Promise.all(node.value.map(async (child) => {
            const childEndpoint = `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`;
            const childRes = await callMsGraph(token, childEndpoint);

            // 当前节点下是图片目录,收集所有图片
            if (childRes.value.length > 0 && 'image' in childRes.value[0]) {
                childRes.value.forEach(imgChild => {
                    images.push({
                        name: imgChild.name,
                        job: imgChild.parentReference.path.split("/")[6],
                        path: imgChild.webUrl
                    });
                });
                return;
            }

            // 非图片目录,递归向下遍历
            await start(childRes);
        }));
    }

    // 等待根节点请求、全量遍历完成
    const rootRes = await callMsGraph(token, rootEndpoint);
    await start(rootRes);
    return images;
};

调用注意

修改后的data函数是异步函数,返回值为Promise,调用时需要用await或者.then()接收结果,路由调用示例:

// 路由处理函数需要加async关键字
router.get('/your-image-path', async (req, res) => {
    const imageList = await shelfdb.data(req.accessToken);
    res.json(imageList);
})

内容的提问来源于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 09:45:38