$http 循环请求和 Angularjs 中的 assemble 数据

$http request over a loop and assemble data in Angularjs

我有一段这样的源码

var projectPromises = $http.get('http://myapi.com/api/v3/projects?private_token=abcde123456');

  $q.all([projectPromises]).then(function(data) {
    console.log(data);
    return data[0];
  }).then(function(projects) {
    var data = projects.data;
    var promises = [];
    var file = [];
    for(var i = 0; i < data.length; i++){
       var url = 'http://myapi.com/api/v3/projects/' + data[i].id + "/owner";
       promises.push($http.get(url));

    }

    console.log(promises);
    $q.all(promises).then(function(user) {
      console.log(user);
    }, function(error) {
      console.log("error here");
      console.log(error);
    });

让我解释一下我的源代码。

首先,我有第一个 API,它将 return 一个项目列表,我将其分配给 projectPromises。在我获得项目列表后,每个项目都将包含一个项目 ID。我将遍历项目列表并触发相应的 http 请求以获取项目的所有者。

之后,我使用 Angular q 模块延迟承诺列表并将列表记录到控制台

console.log(user);

此处不记录任何内容。我尝试打印错误,我知道原因是并非所有项目都包含用户列表。如果不是,它将 return 404 和 200 反之亦然。所以 promises 列表将包含 API 中的 200 和 404 对象 return ,所以我认为当使用 q 延迟 promises 时,如果对象是 404,它会抛出错误。但我不不知道如何解决这个问题。

我的最终目的是获取每个项目的所有者,并将它们填充到一个数组中。

你的承诺过于复杂了。您可以直接绑定到您的 http 调用以与 promise $http returns.

交互
$http.get("http://myapi.com/api/v3/projects?private_token=abcde123456").then(function (results) {
   // projects will be your array of projects
   var projects = results.data;

   // Use native Array for each to get reference to every object in array
   projects.forEach(function (project) {
     $http.get("http://myapi.com/api/v3/projects/' + project.id + "/owner").then(function (results) {
       var data = results.data;
       console.log(data); // This will log your owner
     });
   })
});

您可能应该只将您的所有者与返回的项目嵌套 json 以限制这些无关的 http 请求,但这是服务器端架构的问题。

除非您有多个承诺,否则无需使用 $q.all()$http.get() returns 一个承诺,因此您可以根据该承诺调用 .then

获得项目 ID 列表后,您可以将其映射到一组承诺,每个承诺都有一个 .catch() 以在各自的请求失败时提供回退值。

一旦你有了它,你可以在承诺数组上使用 $q.all(),然后再使用一个 .then(),你应该已经准备就绪。

var pProjects = $http.get('http://myapi.com/api/v3/projects?private_token=abcde123456');

pProjects
    .then(function (result) {
        // map the project IDs to an array of promises for each project's owner
        var pProjectOwners = result.data.map(function (proj) {
            return $http
               .get('http://myapi.com/api/v3/projects/' + proj.id + '/owner')
               .then(function (result) { return result.data; })
               // fallback value to use when a request fails
               .catch(function () { return 'no owner'; });
        });

        return $q.all(pProjectOwners);
    })
    .then(function (projectOwners) {
        console.log(projectOwners);
    })
    .catch(function (error) {
        console.error("something went wrong", error);
    });

这是一个替代版本,其中进行了一些重构以分离出获取项目所有者的操作:

function getProjectOwner(projectId) {
    return $http
       .get('http://myapi.com/api/v3/projects/' + projectId + '/owner')
       .then(function (result) { return result.data; })
}

var pProjects = $http.get('http://myapi.com/api/v3/projects?private_token=abcde123456');

pProjects
    .then(function (result) {
        // map the project IDs to an array of promises for each project's owner
        var pProjectOwners = result.data.map(function (proj) {
            return getProjectOwner(proj.id)
               // fallback value to use when a request fails
               .catch(function () { return 'no owner'; });
        });

        return $q.all(pProjectOwners);
    })
    .then(function (projectOwners) {
        console.log(projectOwners);
    })
    .catch(function (error) {
        console.error("something went wrong", error);
    });