【问题标题】:Nested async requests using request-promise使用 request-promise 的嵌套异步请求
【发布时间】:2016-06-01 14:04:33
【问题描述】:

我正在使用 Visual Studio Online API 并尝试按存储库获取分支统计信息。为此,我嵌套了异步调用。我正在使用 request-promise 来解决我的 GET 请求。

我遇到的问题是了解如何在所有分支都添加到顶级模型后返回模型:

当我控制台记录结果时,我得到[] 显然因为它没有解决分支请求。

var model = [];
rp(options)
  .then(function(repos) {
    repos.value.forEach(function(repository) {
      var repo = {
        id: repository.id,
        name: repository.name,
        branches: []
      };

      var branchOptions = options;
      branchOptions.url = config.endPoints.base + config.endPoints.branches(repository.id);

      rp(branchOptions)
        .then(function(branches) {
          branches.value.forEach(function(branch) {
            repo.branches.push({
              name: branch.name,
              behind: branch.behindCount,
              ahead: branch.aheadCount
            });
          })
        }).then(function() {
          model.push(repo);
        });
    });
  }).finally(function(){
        console.log(model);
        res.json(model);
  });

我尝试在 foreach 之后添加 .then(),但显然 forEach 不会返回承诺。

有什么想法吗?我已经编程了 14 个小时,所以对我来说没有任何意义哈哈。

【问题讨论】:

  • a for each 没有,但如果你使用 .reduce 代替 Promise 链,reduce 将返回一个。 :)
  • 使用map而不是forEach,这样你就可以得到一组promise;然后将其输入Promise.all。或者只是使用 Promise.map,因为您正在使用 bluebird。

标签: node.js express promise bluebird


【解决方案1】:

下面应该解决您的问题,而不是执行 forEach 循环,而是在您的承诺链中将其替换为 .map()。我也在你内心的承诺中做到了这一点。此外,我已经让内部承诺在完成时返回,因此外部地图知道每次迭代何时完成。

我离开了.finally(),因为这表明无论填充model 的结果如何,我们都希望始终响应用户。

我还建议将.catch() 添加到您的外部和内部承诺中,以确保您正确处理任何错误。就目前而言,如果发生错误,则不会处理它,并且将返回 model,并且您永远不会知道在内部或外部 Promise 上使用 .map() 的迭代中发生了错误。

另外值得注意的是request-promise 使用bluebird 实现了A+ Promises。

var model = [];
rp(options)
  .map(function(repository) {
    var repo = {
      id: repository.id,
      name: repository.name,
      branches: []
    };

    var branchOptions = options;
    branchOptions.url = config.endPoints.base + config.endPoints.branches(repository.id);    

    return rp(branchOptions)
      .map(function(branch){ 
        repo.branches.push({
          name: branch.name,
          behind: branch.behindCount,
          ahead: branch.aheadCount
        });
      })
      .then(function() {
        model.push(repo);
      });
  })
  .finally(fuction() {
    console.log(model);
    return res.json(model);
  });

【讨论】:

  • 上面的代码有一些问题: - 最后一个终于有一个错字,在函数中缺少'n'。 - rp(options) 也不会立即返回数据。我必须在.map(function(){}) 之前添加一个.then(function(repository){ return repository.value; }),除此之外它工作得很好。干杯皮特
猜你喜欢
  • 2019-07-21
  • 2016-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-05
  • 2017-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多