我有一个nodejs函数processReviews(workflow)
,当被调用时,应该将多个promise推送到数组promises[]
,然后在for循环后使用promises.all()
运行它们。
function examplePromiseFunc(){
return new Promise((resolve, reject) => {
console.log("examplePromiseFunc() INSIDE ")
resolve('done')
})
}
async function processReviews(workflow){
//get objects from s3
let allObjects = await getAllObjects(workflow);
allObjects = allObjects.filter(obj => obj.Key.includes('output.json'))
console.log(`found ${allObjects.length} .json files.`)
const promises = [];
for (let i = 0; i < allObjects.length; i++) {
console.log('i=',i,' pushing to promises[]')
promises.push( examplePromiseFunc() )
}
const result = await Promise.all(promises)
console.log('running, result = ', result);
}
但是当我运行我的代码时,输出看起来像这样:
found 697 .json files.
i= 0 pushing to promises[]
examplePromiseFunc() INSIDE
i= 1 pushing to promises[]
examplePromiseFunc() INSIDE
i= 2 pushing to promises[]
examplePromiseFunc() INSIDE
i= 3 pushing to promises[]
examplePromiseFunc() INSIDE
...
这意味着每次我将一个promise推送到promise []数组(promises.push( await examplePromiseFunc() )
)时,函数examplePromiseFunc()
都会立即被调用,而不是等待。
我希望我的函数只在最后运行await Promise.all(promises)
时才被调用,是不是我遗漏了什么?我的异步函数会导致问题吗?我一直在阅读javascript promises.all,这似乎是一个很好的实现。
4条答案
按热度按时间e37o9pze1#
问题是您已经在循环中使用了
await
,这意味着循环将“等待”并按顺序处理这些项。相反,你应该只把promises添加到数组中,然后在最后
await
所有的promises,就像你有:3npbholx2#
这里有一个关于
Promise
构造函数如何工作的基本误解。构造函数接受一个称为
executor
的函数参数:executor函数在构造时被同步调用,有两个函数参数,通常称为
resolve
和reject
:promise执行器负责启动异步操作(通常),并使
resolve
和reject
函数可用于处理操作完成和错误处理的代码,通常在回调函数中。所以才有代码
多次调用
examplePromiseFunct
,在该函数中,返回的promise的执行器在构造过程中被同步调用(由Promise
)。因此,日志如人们所期望的那样:每次调用examplePromiseFunc
时的“examplePromiseFunc()INSIDE”日志。这种误解可能导致第二个:
Promise.all
不“运行”promise-promise是被动对象,以确定性的方式响应调用其关联的resolve
和reject
函数,通过调用附加到它们的fulfilled或rejected处理程序-或者如果用promise解析,则链接另一个promise。Promise.all
简单地返回一个promise,该promise通过其参数promise的已实现结果的数组来实现,或被拒绝,并带有拒绝原因或其参数数组中第一个被拒绝的promise。它在本机代码中有一个执行器,可以有效地将then
处理程序附加到其参数数组中的promise,然后被动等待(即,它返回到事件循环),直到一次一个地解决参数承诺。a5g8bdjr3#
这是因为promise只能这样工作。当你把一个promise推入一个数组时,你已经在等待它了(在循环内)即如果你不等待它们执行,那么它们也会执行,有或没有await promise.all,也有可能所有的promise在你把数组传递到promise.all之前就已经解析了。下面的函数也将解析所有没有promise all的promise。
此外,你不应该使用promise.all无限制,因为它可能会达到你的硬件限制。使用一个有限制的Map可以减少你的问题。
fcipmucu4#
没有什么,只是在这种情况下,你必须使用for in或for of循环,因为forEach有时在异步函数中不工作。