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

调用Promise.all()正常执行,单独await Promise无法正确填充数据

问题原因与解决方法

核心问题:forEach不处理异步函数的等待

  • forEach是同步设计的遍历方法,它不会等待传入的异步回调函数执行完成。当你在sectionDef.forEach(async entry => { ... })中编写异步逻辑时,forEach会立刻启动所有异步任务,但不会等待它们全部完成就继续执行后续代码。
  • 你的parseDocumentation是async函数,但它没有等待forEach里的异步任务完成就直接结束了,此时documents数组还没被填充——因为异步请求和文本解析都还在后台执行。

次要问题:异步代码冗余嵌套

第二个方案混合使用await和.then(),导致代码嵌套过深,可读性差且容易出现逻辑疏漏(比如缺失错误处理),但这不是数组未被填充的核心原因。

修正方案

方案1:使用for...of遍历(逻辑清晰,易维护)

async function parseDocumentation(config: Map<string, ConfigElement[]>) {
    const documents: Documentation[] = [];

    // 遍历Map的键值对
    for (const [sectionName, sectionDef] of config.entries()) {
        // 遍历每个section下的entry
        for (const entry of sectionDef) {
            if (!entry.subsection) {
                entry.hash = 'some_hash_value_' + sectionName;
                try {
                    const response = await getRequest(entry.source);
                    if (!response.ok) {
                        throw new Error(`Request failed for ${entry.source}`);
                    }
                    const text = await response.text();
                    documents.push({
                        source: response.url,
                        markDown: text,
                        hash: entry.hash // 直接保存entry.hash
                    });
                } catch (e) {
                    Dialog.error('Failed to load page.', e);
                }
            }
        }
    }
    return documents;
}

方案2:收集Promise再用Promise.all(并行执行,效率更高)

如果希望保持第一个方案的并行请求效率,可以把每个请求+解析逻辑包装成Promise并收集,最后统一等待:

async function parseDocumentation(config: Map<string, ConfigElement[]>) {
    const promises: Promise<Documentation>[] = [];

    config.forEach((sectionDef, sectionName) => {
        sectionDef.forEach(entry => {
            if (!entry.subsection) {
                entry.hash = 'some_hash_value_' + sectionName;
                // 包装单个文档的请求与解析逻辑为Promise
                const docPromise = (async () => {
                    const response = await getRequest(entry.source);
                    if (!response.ok) {
                        throw new Error(`Request failed for ${entry.source}`);
                    }
                    const text = await response.text();
                    return {
                        source: response.url,
                        markDown: text,
                        hash: entry.hash
                    };
                })();
                promises.push(docPromise);
            }
        });
    });

    try {
        const documents = await Promise.all(promises);
        return documents;
    } catch (e) {
        Dialog.error('Failed to load page.', e);
        return [];
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 07:15:57