$http循环请求并在Angularjs中组装数据

$http request over a loop and assemble data in Angularjs

本文关键字:数据 Angularjs http 循环 请求      更新时间:2023-09-26

我有一段这样的源代码

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,它将返回项目列表,并分配给projectPromises。我拿到项目列表后,每个项目都会包含一个项目ID。我将遍历项目列表并触发相应的 http 请求以获取项目的所有者。

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

console.log(user);

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

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

除非您有多个承诺,否则无需使用$q.all()$http.get()返回一个承诺,因此您只需根据该承诺调用.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);
    });

你把你的承诺做得太复杂了。您可以直接绑定到 http 调用,以便与承诺$http返回进行交互。

$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 请求,但这是服务器端架构的问题。