Angular combinando solicitudes paralelas y encadenadas con $ http.then () y $ q.all ()
Tengo que hacer un conjunto bastante complicado de llamadas a la API y estoy intentando hacerlo de la manera más elegante y eficaz posible. Entiendo cómo usar la promesa api del$http
servicio a las solicitudes en cadena, y cómo utilizar el$q
Servicio para realizar solicitudes en paralelo. Pero para este flujo de trabajo específico de API necesito hacer ambas cosas.
Aquí hay un ejemplo del flujo de API de alto nivel:
/dog/<dog_id>
/breed/<breed_id>
/food/<food_id>
/cat/<cat_id>
/turkey/<turkey_id>
/fish/<fish_id>
El primer nivel de solicitudes todas tienen identificadores conocidos. Sin embargo, el<breed_id>
requerido para hacer el/breed
la llamada debe ser analizada desde el/dog
respuesta, y la<food_id>
requerido para hacer el/food
la llamada debe ser analizada desde el/breed
respuesta. Asi que/dog
, /breed
y/food
todos necesitan ser encadenados sin embargo/cat
, /turkey
y/fish
Se puede hacer en paralelo con toda la/dog
cadena.
Lo que tengo ahora (y está funcionando bien) son dos conjuntos de solicitudes separadas. ¿Cómo puedo mejorar este flujo? ¿Hay una manera de combinar las dos pilas de una manera que resulte en una sola promesa de ejecución de.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();
});