【问题标题】:Execute an Array of promises sequentially without using async/await在不使用 async/await 的情况下按顺序执行一组 Promise
【发布时间】:2019-09-14 14:35:00
【问题描述】:

假设我有一系列的承诺。我的数组的每个元素都是一个 knex.js 查询构建器,可以执行并返回一个 Promise。

如何按顺序运行此数组的每个元素。 数组是动态构建的。

let promisesArray = [q1,q2,q3] ;

每个 q 本身并不是一个 Promise,但它会在执行时返回一个 Promise。

【问题讨论】:

标签: javascript node.js promise


【解决方案1】:

这可能是一个可能的选择:

let p = Promise.resolve([]);
promisesArray.forEach(q => {
  p = p.then(responses => {
    //based on the nature of each q, to start execution
    //use either q().then() or q.then()
    return q().then(response => {
      //Any further logic can be here.
      console.log(response);
      return responses.concat([response]);
    })
  })
})

p.then(responses => {
  // here you have all of the responses.
})

【讨论】:

  • 使用reduce,这是一行promisesArray.reduce((p, q) => p.then(responses => q.then(response => [...responses, response])), Promise.resolve([]))
  • 不是真的,@Nnanyielugo - 取决于我猜你知道的情况
  • 单行字通常不难读给他们的作者 :-)
【解决方案2】:

您可以使用 Array.reduce 将 Array 缩减为一个将它们一个接一个链接起来的 Promise

let promisesArray = [q1,q2,q3] ;

function runSequentially(promiseArr) {
  return promiseArr.reduce((accum, p) => accum.then(p), Promise.resolve())
}

//Example, this prints.. 1, 2, 3 then "done".
runSequentially([Promise.resolve(1).then(console.log), Promise.resolve(2).then(console.log), Promise.resolve(3).then(console.log)]).then(() => console.log("done"))

【讨论】:

    【解决方案3】:

    我可以想到 bluebird promise,它应该可以解决您的问题。将并发值保持为 1,应按顺序执行 Promise。

        var Promise = require("bluebird");
        Promise.map([q1,q2,q3], {concurrency: 1})
    

    【讨论】:

    • 我真的很想知道,为什么会投反对票。你认为它不会起作用吗?
    【解决方案4】:

    根据您声称 q1、q2、q3 是“knex.js 查询构建器并准备好执行并返回一个承诺”,获取一个函数以在承诺解决时使用下一个索引执行自身。先用 0 调用它。

    function awaitPromise(arr, idx) {
    
       arr[idx]().then(function(res) {
    
           console.log(res);
    
           if (idx < arr.length - 1)      
               awaitPromise(arr, idx + 1);
       })
    }
    

    【讨论】:

      【解决方案5】:

      如果您使用的是bluebird,则可以使用Promise.map,并将并发设置为1

      await Promise.map(arrayOfObj, async (obj) => {
          await this.someOperation();
        },
        {concurrency: 1}
      );
      

      【讨论】:

        猜你喜欢
        • 2021-09-30
        • 2020-02-06
        • 2022-08-14
        • 1970-01-01
        • 1970-01-01
        • 2021-04-27
        • 2019-07-01
        • 2020-08-16
        • 1970-01-01
        相关资源
        最近更新 更多