使用$ http.then()和$ q.all()将并行和链接请求进行角度组合

时间:2013-11-27 20:38:26

标签: javascript angularjs promise

我有一组相当复杂的API调用,我试图尽可能优雅和高效。我了解如何使用$http服务的promise api来链接请求,以及如何使用$q服务并行发出请求。但是对于这个特定的API工作流程,我需要同时做这两件事。

以下是高级API流程的示例:

  • /dog/<dog_id>
    • /breed/<breed_id>
      • /food/<food_id>
  • /cat/<cat_id>
  • /turkey/<turkey_id>
  • /fish/<fish_id>

第一层请求都有已知的ID。但是,必须从<breed_id>响应中解析进行/breed调用所需的/dog,并且必须解析进行<food_id>调用所需的/food /breed回复。/dog因此/breed/food/cat都需要链接。但是,/turkey/fish/dog可以与整个.then()链并行生成。

我现在所拥有的(并且工作正常)是两组独立的请求。如何改进此流程?有没有办法以导致var dogId = '472053', catId = '840385', turkeyId = '240987', fishId = '510412'; var myData = {}; var firstSetComplete = false, secondSetComplete = false, returnData = function() { if (firstSetComplete && secondSetComplete) { console.log("myData.dog", myData.dog); console.log("myData.dog.breed", myData.dog.breed); console.log("myData.dog.food", myData.dog.food); console.log("myData.cat", myData.cat); console.log("myData.turkey", myData.turkey); console.log("myData.fish", myData.fish); } }; // first call set $http.get('http://example.com/dog/' + dogId) .then(function(response) { myData.dog = response.data; return $http.get('http://example.com/breed/' + response.data.breed_id); }) .then(function(response) { myData.dog.breed = response.data; return $http.get('http://example.com/food/' + response.data.food_id); }) .then(function(response) { myData.dog.food = response.data; firstSetComplete = true; returnData(); }); // second call set $q.all([ $http.get('http://example.com/cat/' + catId), $http.get('http://example.com/turkey/' + turkeyId), $http.get('http://example.com/fish/' + fishId) ]) .then(function(responses) { myData.cat = responses[0].data; myData.turkey = responses[1].data; myData.fish = responses[2].data; secondSetComplete = true; returnData(); }); 的单个承诺执行的方式组合两个堆栈?

{{1}}

1 个答案:

答案 0 :(得分:47)

您可以像这样传递第一个链:

$q.all([
    $http.get('http://example.com/cat/' + catId),
    $http.get('http://example.com/turkey/' + turkeyId),
    $http.get('http://example.com/fish/' + fishId),
    $http.get('http://example.com/dog/' + dogId)
    .then(function(response) {
         myData.dog = response.data;
         return $http.get('http://example.com/breed/' + response.data.breed_id);
     })
     .then(function(response) {
         myData.dog.breed = response.data;
         return $http.get('http://example.com/food/' + response.data.food_id);
     })
     .then(function(response) {
         myData.dog.food = response.data;
         return myData;
     })
])
.then(function(responses) {
    myData.cat = responses[0].data;
    myData.turkey = responses[1].data;
    myData.fish = responses[2].data;

    secondSetComplete = true;
    returnData();
});

狗的承诺链最终会返回一个单一的承诺,当最后一个then被调用时它会被解决,并且它会从最终函数的结果中解析出来。因此,没有理由不能将其嵌套在$q.all()电话中。