Javascript 我如何在一个承诺循环后运行回调?

Javascript 我如何在一个承诺循环后运行回调?,javascript,node.js,promise,Javascript,Node.js,Promise,具体地说,给定一个数据列表,我想在该列表上循环,并对该数据的每个元素进行提取,然后再将其合并。正如所写的那样,代码立即遍历整个列表,同时启动所有操作。然后,即使fetch操作仍在运行,我在运行了所有这些操作之后,在处理数据之前进行的Then调用 我读了一些关于将所有承诺放入一个数组中,然后将该数组传递给一个Promise.all()调用,然后是一个then,该调用将按预期访问所有处理过的数据,但我不确定在这种情况下如何进行,因为我在这个for循环中嵌套了承诺 for(var i

具体地说,给定一个数据列表,我想在该列表上循环,并对该数据的每个元素进行提取,然后再将其合并。正如所写的那样,代码立即遍历整个列表,同时启动所有操作。然后,即使fetch操作仍在运行,我在运行了所有这些操作之后,在处理数据之前进行的Then调用

我读了一些关于将所有
承诺
放入一个数组中,然后将该数组传递给一个Promise.all()调用,然后是一个then,该调用将按预期访问所有处理过的数据,但我不确定在这种情况下如何进行,因为我在这个for循环中嵌套了
承诺

        for(var i in repoData) {
            var repoName = repoData[i].name;
            var repoUrl = repoData[i].url;
            (function(name, url) {
                Promise.all([fetch(`https://api.github.com/repos/${username}/${repoData[i].name}/commits`),
                    fetch(`https://api.github.com/repos/${username}/${repoData[i].name}/pulls`)])
                .then(function(results) {   
                    Promise.all([results[0].json(), results[1].json()])
                    .then(function(json) {
                        //console.log(json[0]);
                        var commits = json[0];
                        var pulls = json[1];
                        var repo = {};
                        repo.name = name;
                        repo.url = url;
                        repo.commitCount =  commits.length;
                        repo.pullRequestCount = pulls.length;
                        console.log(repo);
                        user.repositories.push(repo);
                    }); 
                });
            })(repoName, repoUrl);
        }
    }).then(function() {
        var payload = new Object();
        payload.user = user;
        //console.log(payload);
        //console.log(repoData[0]);
        res.send(payload);
    });

通常,当需要对数组中的所有项运行异步操作时,答案是使用
Promise.all(arr.map(…)
,这种情况似乎也不例外

还请记住,您需要在
然后
回调中返回值,以便将值传递到下一个
然后
(或传递到
承诺。所有
聚合所有内容)

当面对一个复杂的情况时,把它分解成更小的部分是很有帮助的。在这种情况下,您可以将用于查询单个回购数据的代码隔离到它自己的函数中。完成此操作后,查询所有数据的代码归结为:

Promise.all(repoData.map(function (repoItem) {
  return getDataForRepo(username, repoItem);
}))
请尝试以下操作:

// function to query details for a single repo
function getDataForRepo(username, repoInfo) {
  return Promise
    .all([
      fetch(`https://api.github.com/repos/${username}/${repoInfo.name}/commits`),
      fetch(`https://api.github.com/repos/${username}/${repoInfo.name}/pulls`)
    ])
    .then(function (results) {
      return Promise.all([results[0].json(), results[1].json()])
    })
    .then(function (json) {
      var commits = json[0];
      var pulls = json[1];

      var repo = {
        name: repoInfo.name,
        url: repoInfo.url,
        commitCount: commits.length,
        pullRequestCount: pulls.length
      };

      console.log(repo);
      return repo;
    });
}

Promise.all(repoData.map(function (repoItem) {
  return getDataForRepo(username, repoItem);
})).then(function (retrievedRepoData) {
  console.log(retrievedRepoData);

  var payload = new Object();
  payload.user = user;
  //console.log(payload);
  //console.log(repoData[0]);
  res.send(payload);
});

通常,当需要对数组中的所有项运行异步操作时,答案是使用
Promise.all(arr.map(…)
,这种情况似乎也不例外

还请记住,您需要在
然后
回调中返回值,以便将值传递到下一个
然后
(或传递到
承诺。所有
聚合所有内容)

当面对一个复杂的情况时,把它分解成更小的部分是很有帮助的。在这种情况下,您可以将用于查询单个回购数据的代码隔离到它自己的函数中。完成此操作后,查询所有数据的代码归结为:

Promise.all(repoData.map(function (repoItem) {
  return getDataForRepo(username, repoItem);
}))
请尝试以下操作:

// function to query details for a single repo
function getDataForRepo(username, repoInfo) {
  return Promise
    .all([
      fetch(`https://api.github.com/repos/${username}/${repoInfo.name}/commits`),
      fetch(`https://api.github.com/repos/${username}/${repoInfo.name}/pulls`)
    ])
    .then(function (results) {
      return Promise.all([results[0].json(), results[1].json()])
    })
    .then(function (json) {
      var commits = json[0];
      var pulls = json[1];

      var repo = {
        name: repoInfo.name,
        url: repoInfo.url,
        commitCount: commits.length,
        pullRequestCount: pulls.length
      };

      console.log(repo);
      return repo;
    });
}

Promise.all(repoData.map(function (repoItem) {
  return getDataForRepo(username, repoItem);
})).then(function (retrievedRepoData) {
  console.log(retrievedRepoData);

  var payload = new Object();
  payload.user = user;
  //console.log(payload);
  //console.log(repoData[0]);
  res.send(payload);
});

这不是你应该如何使用承诺…问题中的代码是否完整?最后一个
.then()
链接到什么?这不是你应该如何使用承诺…问题代码是否完整?最后一个
.then()
链接到什么?