2013-03-26 5 views
8

OK, disons que j'ai un tableau de n demandes XHR:Chaînage un nombre inconnu de promesses dans AngularJS

var promises = []; 
var AllResults = []; 
$scope.requests = [ 
    { 
     "uri":"http://foo/bar/action1", 
     "name":"Action1" 
    },{ 
     "uri":"http://bar/foo/action2", 
     "name":"Action2" 
    },{...},{...},{...} 
]; 
var ParseMyResultsArray = function(){ 
    console.log(AllResults); 
    //... 
}; 

angular.forEach($scope.requests, function(request){ 
    var promise = $http.get(request.uri); 
    promises.push(promise); 
}); 

angular.forEach(promises, function(promise){ 
    promise.then(function(results){ 
     AllResults.push(results); 
    }); 
}); 

//Then, when all promise are resolved... 
ParseMyResultsArray(); 

Comment puis-je être sûr d'appeler ParseMyResultsArray() lorsque toutes les promesses sont résolues sans le savoir la taille de mon tableau requests?

Merci pour votre aide!

Répondre

17

De docs angulaires à $http:

L'API $ http est basée sur les API différés/promesse exposés par le q $ de service .

Il est donc possible d'utiliser la méthode $q.all() qui prend un tableau de promesses et:

combine plusieurs promesses en une seule promesse qui est résolu quand toutes les promesses d'entrée sont résolues

Le code de mise en œuvre est:

$q.all(promises).then(function() { /* All promises are resolved */ }); 
8

Je sais que cette question a plus d'un an mais elle mérite une meilleure réponse.

Le code peut être beaucoup plus concis et les vars externes laids promises et AllResults et la fonction externe ParseMyResultsArray() peuvent être évités.

Essayez ...

$scope.requests = [{ 
     "uri":"http://foo/bar/action1", 
     "name":"Action1" 
    }, { 
     "uri":"http://bar/foo/action2", 
     "name":"Action2" 
    },{...},{...},{... 
}]; 

$q.all($scope.requests.map(function(request) { 
    return $http.get(request.uri); 
})).then(function(results) { 
    console.log(results); 
    //parse results array here ... 
    return parsedResults; 
}); 

Si l'accès à plus parsedResults est nécessaire, par tous les moyens de garder (ou retourner) une référence à la promesse retournée par $q.all(...).then(...). En raison de l'asynchronicité impliquée dans l'obtention des données, cette promesse de parsedResults sera beaucoup plus utile que la variable externe brute AllResults.