首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >promises.push()立即运行,不等待promises.all()

promises.push()立即运行,不等待promises.all()
EN

Stack Overflow用户
提问于 2021-01-21 08:47:40
回答 3查看 175关注 0票数 0

我有一个nodejs函数processReviews(workflow),当它被调用时,应该将多个promises推送到一个数组promises[],然后在for循环之后用promises.all()运行它们。

代码语言:javascript
复制
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);
}

但是当我运行我的代码时,输出如下所示:

代码语言:javascript
复制
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
...

这意味着每次我向promises[]数组(promises.push( await examplePromiseFunc() ))推送一个promise时,examplePromiseFunc()函数都会立即被调用,而不是等待。

我希望我的函数在最后运行await Promise.all(promises)时才会被调用,是不是我遗漏了什么?我的异步函数是否导致了问题?我一直在研读javascript promises.all,这看起来是一个很好的实现。

EN

回答 3

Stack Overflow用户

发布于 2021-01-21 08:53:13

相反,您只需将promises添加到数组中,然后在最后await所有它们,就像您所做的那样:

代码语言:javascript
复制
async function processReviews(workflow) {
  //get objects from s3
  const allObjects = await getAllObjects(workflow);

  const promises = [];
  for (let i = 0; i < allObjects.length; i++) {
    // Don't await the promise here, just start it and add it to the array.
    promises.push(examplePromiseFunc(allObjects[i]));
  }
  const result = await Promise.all(promises)
  console.log(result);
        
}
票数 1
EN

Stack Overflow用户

发布于 2021-01-21 09:49:06

这里对Promise构造函数的工作方式有一个根本性的误解。

构造函数只接受一个称为executor的函数参数

代码语言:javascript
复制
new Promise( executor)

在构造过程中,执行器函数被称为同步,它有两个函数参数,通常称为resolvereject

代码语言:javascript
复制
executor( resolve, reject)

promise executor负责启动异步操作(通常),并使resolvereject函数可用于处理操作完成和错误处理的代码,通常是在回调函数中。

因此代码

代码语言:javascript
复制
    for (let i = 0; i < allObjects.length; i++) {
        console.log('i=',i,' pushing to promises[]')
        promises.push( examplePromiseFunc() )
    }

多次调用examplePromiseFunct,在该函数中,返回的promise的executor在构造期间被同步调用(由Promise调用)。因此,日志与预期不谋而合:每次调用examplePromiseFunc时,都会出现"examplePromiseFunc() INSIDE“的日志。

这种误解可能会导致第二个误解:

Promise.all不“运行”promise - promises是被动对象,通过调用附加到它们的已履行或已拒绝的处理程序,以确定性的方式响应调用其关联的resolvereject函数-或者链接另一个promise (如果使用promise解析)。

Promise.all只返回一个promise,该promise由其参数promises的已履行结果数组实现,或者被拒绝,并带有拒绝原因或其参数数组中的第一个promise变为rejected。它在本机代码中有一个执行器,可以有效地将then处理程序附加到其参数数组中的promises,然后被动地等待(即,它返回到事件循环),直到参数promises一次解决一个。

票数 1
EN

Stack Overflow用户

发布于 2021-01-21 10:21:38

这是因为承诺只以这种方式工作。当你将一个promise推入一个数组时,你已经在等待它了(在循环中),也就是说,如果你不想等待它们执行,那么它们也会执行,不管有没有await promise.all,也有可能在你将该数组传递到promise.all之前,所有的promise都已经被解析了。下面的函数还将解析所有没有promise all的promise。

代码语言:javascript
复制
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() )
        }
}

此外,您不应该无限制地使用promise.all,因为它可能会达到您的硬件的限制。使用有限制的map可以减少您的问题。

代码语言:javascript
复制
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.`);

  for (let i = 0; i < allObjects.length; i = i + PROMISE_LIMIT) {
    const objects = allObjects.slice(i, i + PROMISE_LIMIT);
    const result = await Promise.all(objects.map(elem => examplePromiseFunc()));
    console.log("running, result = ", result);
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65819710

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档