简体   繁体   English

动态创建承诺并按顺序运行

[英]Dynamically creation of promises and running sequentially

I'm running into the following problem. 我遇到了以下问题。

I have the following promise (simplified): 我有以下承诺(简化):

module.exports.checkVotes = (groupId) =>{
    return new Promise((resolve, reject)=>{
     // some db stuff onoing
     ...
     .then((votes)=>{return resolve(votes}})
     .catch((err)=>{return reject(err}})
    })
}

At some point I'm looping through an object. 在某些时候,我正在遍历一个对象。 For each entry i have to call promise above. 对于每个条目,我必须致电上述的promise。 But before the 2. Promise starts, the first one have to be finished...and so on. 但是,在“ 2.承诺”开始之前,第一个必须完成...依此类推。 I tried this, but as soon as I call the promise it gets executed. 我尝试了此操作,但是一旦我将其称为promise,它就会被执行。

 .then(()=>{
      for (let i=0;i<groups.length;i++){
           // for each group I want to call the promise later
           //but it executes as soon as I push it.
           tasklist.push(this.checkVotes(groups[i])) 
       }

       return tasklist.reduce((promiseChain, currentTask) => {
           return promiseChain.then(chainResults =>
               currentTask.then(currentResult =>
                    [ ...chainResults, currentResult ]
                )
           );
        }, Promise.resolve([])).then(arrayOfResults => {
                console.log(arrayOfResults)
            }).catch((err) =>{console.log(err)});
         })
  })

I can not run this with Promise.all() because for some database things, I need this to run sequentially. 我无法使用Promise.all()运行此程序,因为对于某些数据库而言,我需要此程序按顺序运行。 Moreover I can not hardcode this because the number of groups is variable. 此外,我无法对此进行硬编码,因为组的数量是可变的。

How can I solve this? 我该如何解决?

Thanks for helping 感谢您的帮助

Your problem was with putting promises in the taskList , not tasks (functions that return promises). 您的问题是将promise放入taskList ,而不是任务(返回promise的函数)。 The idea behind making them run in sequence is to call them in the then callback in the reduce : 使它们依次运行的想法是在reducethen回调中调用它们:

return groups.reduce((promiseChain, currentGroup) => {
    return promiseChain.then(chainResults =>
        this.checkVotes(currentGroup).then(currentResult => [...chainResults, currentResult])
//      ^^^^^^^^^^^^^^^
    );
}, Promise.resolve([]))

But if you can use async / await syntax, you don't need to do all of this anyway and can write the much simpler and more efficient 但是,如果您可以使用async / await语法,则无需执行所有这些操作,并且可以编写更简单,更有效的代码

const results = [];
for (const group of groups)
    results.push(await this.checkVotes(group));

seems to work like this: 似乎像这样工作:

groupIds = [12, 45, 34];
return groupIds .reduce((promise, groupId) => {
                return promise.then(() => {
                    return this.checkVotes(groupId)
                        .then((votes)=>{
                            votesList[groupId] = votes
                        })
                        .catch((err)=>{
                            throw err
                        })
                })
            }, Promise.resolve())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM