调用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
相关产品推荐
相关产品推荐

