【问题标题】:Why is this promise chain not returning sequentially?为什么这个承诺链没有按顺序返回?
【发布时间】:2020-04-14 06:14:28
【问题描述】:

我正在尝试创建一个承诺链,它按照调用顺序返回结果,因为这对我的应用程序很重要。然而,尽管我进行了多次尝试,但由于输出 resultArray 回来时交换了一些数据点,这使得下游处理变得混乱,因此我仍在苦苦挣扎。这就是我目前拥有的(在

上找到
Promise.all(data.map( (dataPoint) => {
  return new Promise( (resolve, reject) => {
    doSomething(dataPoint).then( (result) => {
      resultArray.push(result);
      resolve();
    });
  })
})).then( () => {
    res.status(201).json({"result": resultArray});
});

我也尝试过以下模式,但这只是返回 [] 作为 promise.all 似乎并没有等待承诺按预期完成:

let p = Promise.resolve();
data.forEach(dataPoint => {
  p = p.then( () => {
    getElevation(dataPoint, options).then( (result) => {
      resultArray.push(result);
    });
  });
});

Promise.all([p]).then( () => {
  res.status(201).json({"result": resultArray});
});

更新

虽然写的问题得到了回答,但我现在意识到接受的答案不会等待每个承诺在下一个启动之前返回。它确实对它们进行了映射,以便输出按正确的顺序排列,但我需要每次调用都了解最后一次调用 - 我如何简洁地实现这一点?

【问题讨论】:

    标签: javascript node.js express promise


    【解决方案1】:

    如果您希望每个 Promise 在下一个 Promise 之前完全解决,您可以使用 async/await 模式。这样,每个调用都可以访问先前调用的所有结果。

    async function run(options) {
      const results = [];
      for(let dataPoint of data) {
        const result = await getElevation(dataPoint, options);
        results.push(result);
      }
      return results;
    }
    
    run(options).then(result => {
      res.status(201).json({ result });
    });
    

    【讨论】:

      【解决方案2】:

      如果您想按顺序获取数据,请不要使用forEach & [].push。将 Promise 添加到数组并将该 Promise 数组传递给 Promise.all,这将为您保留订单。

      你的let p = Promise.resolve() 行也没有任何意义,它只是给你的代码增加了噪音。

      使用.map获取getElevationpromise的数组,并将其传递给Promise.all,当它解析时,结果将与data数组具有相同的顺序。

      const promises = data.map(dataPoint => getElevation(dataPoint, options));
      
      Promise.all(promises).then(result => {
        res.status(201).json({ result });
      });
      

      【讨论】:

      • 感谢您的解释 - 正如我在更新中所做的那样,如果不是我所需要的,它非常有用(但这是由于我的问题很糟糕,而不是您的好答案!)但是,您介意解释一下吗您的观点:“您的 let p = Promise.resolve() 行也没有任何意义”??我已经看到之前讨论过的模式,例如:stackoverflow.com/questions/55296452/…。为什么在这种情况下没有意义?
      • 因为您希望结果按顺序排列,将单个承诺传递给 Promise.all 不会实现这一点。该模式适用于链接,而不是您想要做的事情。
      猜你喜欢
      • 2020-03-24
      • 1970-01-01
      • 2016-11-23
      • 2021-01-28
      • 2020-08-23
      • 1970-01-01
      • 2013-11-10
      • 2021-10-31
      • 1970-01-01
      相关资源
      最近更新 更多