首页 文章

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

提问于
浏览
0

我遇到了以下问题 .

我有以下承诺(简化):

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

在某些时候,我正在循环一个对象 . 对于每个条目,我必须在上面打电话给承诺 . 但在2. 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)});
         })
  })

我无法使用Promise.all()运行它,因为对于某些数据库的东西,我需要它按顺序运行 . 此外,我不能硬编码,因为组的数量是可变的 .

我怎么解决这个问题?

谢谢你的帮助

2 回答

  • 0

    你的问题在于将承诺放在 taskList 中,而不是任务(返回承诺的函数) . 让它们按顺序运行的想法是在 reduce 中的 then 回调中调用它们:

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

    但是如果你可以使用 async / await 语法,那么无论如何都不需要做所有这些,并且可以编写更简单,更高效的语法

    const results = [];
    for (const group of groups)
        results.push(await this.checkVotes(group));
    
  • 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())
    

相关问题