我正在尝试将async
/ await
与reduce
方法一起使用。但是以某种方式,只有循环的第一次迭代才起作用。一旦完成第一个await
迭代,papers对象将跳过reduce
。是否可以使用reduce
创建对象,同时从承诺中收集对象的内容,同时还要等待整个过程?
减少功能:
const papers = await page.concepts.reduce(async (acc, cur) => {
acc[cur.paperID] = await getPageData(`papers/${ cur.paperID }`, 'md')
return acc
}, {})
注意:getPageData
返回一个承诺。
您可以创建一个承诺数组,然后使用Promise.all
来解决它们。如果任何请求失败,则Promise.all
将停止处理其余请求。
const papersPromises = page.concepts.map(cur =>
getPageData(`papers/${ cur.paperID }`, 'md')
)
const result = await Promise.all(papersPromises)
// result will be an array with the results
这是将数组折叠成一个对象的一种方法,但是自然地,它不会处理异步函数并减少自身。另外,reduce不会返回Promise等待
您可以使用Promise.all和Object.fromEntries解决您的情况>
// map concepts to promises which will resolve to page data for each concept // and await for them all at once (will run in parallel) const pageResponses = await Promise.all(page.concepts.map(concept => getPageData(`papers/${concept.paperID}`, 'md'))) // construct object where keys are concept.paperIDs and values are pageDatas const papers = Object.fromEntries( page.concepts .map((concept, i) => ([concept.paperID, pageResponses[i]])) )
如果您的运行时不支持Object.fromEntries(并且您没有使用polyfill),则可以像这样做最后一部分
const papers = page.concepts.reduce((acc, concept, index) => acc[concept.paperID] = pageResponses[index], {})
由于异步函数返回一个Promise,所以您必须期望累加器是一个Promise。因此,您将执行以下操作: