使用请求-承诺的嵌套异步请求

Nested async requests using request-promise

本文关键字:请求 嵌套 异步 承诺      更新时间:2023-09-26

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

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

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

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 个小时,所以对我来说没有什么意义哈哈。

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

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

我还建议在你的外在和内在承诺中添加.catch(),以确保你适当地处理任何错误。就目前而言,如果发生错误,则没有任何内容可以处理它,并且model将被返回,并且您永远不会知道在内部或外部承诺的.map()的一次迭代中发生了错误。

还值得注意的是,request-promise 使用 bluebird 实现 A+ 承诺。

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