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, /breedy/food todos necesitan ser encadenados sin embargo/cat, /turkeyy/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();
});

Respuestas a la pregunta(1)

Su respuesta a la pregunta