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

时间:2018-12-09 13:46:16

标签: javascript node.js promise sequential

我遇到了以下问题。

我有以下承诺(简化):

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

在某些时候,我正在遍历一个对象。对于每个条目,我必须致电上述的promise。但是,在“ 2.承诺”开始之前,第一个必须完成...依此类推。 我试过了,但是一旦我叫出诺言,它就会被执行。

 .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)});
         })
  })

我无法使用Promise.all()运行此程序,因为对于某些数据库而言,我需要此程序按顺序运行。此外,我无法对此进行硬编码,因为组的数量是可变的。

我该如何解决?

感谢您的帮助

2 个答案:

答案 0 :(得分:0)

您的问题是将承诺放入taskList中,而不是任务(返回承诺的函数)。使它们依次运行的想法是在then的{​​{1}}回调中调用

reduce

但是,如果您可以使用return groups.reduce((promiseChain, currentGroup) => { return promiseChain.then(chainResults => this.checkVotes(currentGroup).then(currentResult => [...chainResults, currentResult]) // ^^^^^^^^^^^^^^^ ); }, Promise.resolve([])) / async语法,则您无需执行所有这些操作,而是可以编写更简单,更有效的方法

await

答案 1 :(得分:0)

似乎可以这样工作:

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())
相关问题