我有一些代码可以迭代表示文件的对象列表。在循环中有一个对“getRequest()”的调用,它返回类型“Promise”,然后是对“.text()”的调用,它返回“Promise”。我有一个工作解决方案,首先将所有的Promise放入列表中,然后调用Promise.all(),文档就被正确获取了。
但是,当我尝试另一个解决方案时,我直接等待promise返回,然后使用这些值,文档没有正确填充。
//----------------------------- WORKING SOLUTION ---------------------------------------
async function parseDocumentation(config: Map<string, ConfigElement[]>) {
const promises: Promise<Response>[] = [];
const documents: Documentation[] = [];
config.forEach((sectionDef: ConfigElement[]) => {
sectionDef.forEach(entry => {
if (!entry.subsection) {
// getRequest: (endpointUrl: string) => Promise<Response>
promises.push(getRequest(entry.source));
}
});
});
try {
await Promise.all(promises).then(async responses => {
for (const response of responses) {
if (!response.ok) {
return Promise.reject();
} else {
const document = {source: '', markDown: '' };
document.markDown = await entry.text(); // Body.text(): Promise<string>
document.source = response.url;
documents.push(document);
}
}
});
} catch (e) {
Dialog.error('Failed to load page.', e);
}
}
//----------------------------- NON WORKING SOLUTION ---------------------------------------
async function parseDocumentation(config: Map<string, ConfigElement[]>) {
const documents: Documentation[] = [];
config.forEach((sectionDef: ConfigElement[], sectionName: string) => {
sectionDef.forEach(async entry => {
if (!entry.subsection) {
entry.hash = 'some_hash_value_' + sectionName;
await getRequest(entry.source).then(async response => {
if (!response.ok) {
return Promise.reject();
} else {
const document = {source: '', markDown: '' };
await response.text().then(async text => {
// would like to save entry.hash to document here
document.markDown = text;
document.source = response.url;
documents.push(document);
});
}
});
}
});
});
}
有人能解释一下发生了什么吗?我想我正确地反映了逻辑,但由于某种原因,第二个变体没有正确地填充文档。
2条答案
按热度按时间yacmzcpb1#
问题出在
.forEach(async ....
构造上:回调是一个异步函数,其中的第一个await
将返回/suspend * 该 * 回调函数(不是外部函数),使forEach
循环继续下一次迭代。回调中的异步代码(await
以下)仅在调用堆栈为空时执行,因此forEach
在此之前已经完成了迭代。要解决这个问题,使用一个不需要回调的循环结构,比如
for..of
。然后await
对parseDocumentation
函数本身进行操作:问题不在于此,而是要尽量从
await
中获得所承诺的价值--避免then
链:请注意,在
async
函数中抛出错误将拒绝函数返回的承诺,原因是错误消息。oxiaedzo2#
您应该:
let text = await response.text();