Подтвердить что ты не робот

Angular, объединяющий параллельные и закодированные запросы с параметрами $http.then() и $q.all()

У меня довольно сложный набор вызовов API, и я пытаюсь сделать это как можно более элегантно и качественно. Я понимаю, как использовать обещание api службы $http для запросов на цепочку и как использовать службу $q для параллельного выполнения запросов. Но для этого конкретного рабочего процесса API мне нужно сделать оба.

Ниже приведен пример потока API верхнего уровня:

  • /dog/<dog_id>
    • /breed/<breed_id>
      • /food/<food_id>
  • /cat/<cat_id>
  • /turkey/<turkey_id>
  • /fish/<fish_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();
});
4b9b3361

Ответ 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();
});

Эта большая цепочка promises для собак заканчивается возвратом единственного обещания, которое разрешается при вызове последнего then и разрешается с результатом этой конечной функции. Поэтому нет причин, по которым вы не можете вложить его в свой вызов $q.all().