一尘不染

Angular将并行和链接请求与$ http.then()和$ q.all()组合

angularjs

我要进行一组相当复杂的API调用,并且我尝试尽可能地做到优雅和高效。我了解如何使用服务的promise api
$http来链接请求,以及如何使用$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链条平行。

我现在所拥有的(并且工作正常)是两组独立的请求。我如何改善这一流程?有没有一种方法可以将两个堆栈组合在一起,从而导致一个单次执行Promise
.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();
});

阅读 297

收藏
2020-07-04

共1个答案

一尘不染

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

$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()呼叫中。

2020-07-04