it-swarm.com.de

AngularJS wartet auf alle asynchronen Anrufe innerhalb von foreach

Ich schleife durch ein Array mit angle.forEach und rufe eine nicht-winklige Ajax-Bibliothek (Trello-Client.js) auf. Der Client hat 'Rückrufe' für 'Erfolg' und 'Fehler', gibt jedoch keinen zurückgestellten Winkel zurück. Ich möchte eine Funktion ausführen, wenn alle Ajax-Aufrufe abgeschlossen sind. 

Ich habe folgenden Code:

$scope.addCards = function(listId)
            {
                var cardTitles = $scope.quickEntryCards[listId].split('\n');
                angular.forEach(cardTitles, function(cardTitle,key)
                {
                    Trello.post('/cards', {
                        name:cardTitle,
                        idList:listId
                    },function(){ }, function(){ });
                });
                //TODO: wait for above to complete...
                $scope.init($routeParams.boardId);  
                $scope.quickEntryCards[listId] = '';    
            };

Was kann ich bei // TODO und in den Callback-Funktionen tun, damit die letzten beiden Zeilen erst ausgeführt werden, wenn alle Beiträge entweder erfolgreich sind oder fehlschlagen?

9
Daniel

pseudo-Code unter Verwendung des $ q-Dienstes von angle.

requests = [];

forEach cardTitle
   var deferred = $q.defer();
   requests.Push(deferred);
   Trello.post('/path', {}, deferred.resolve, deferred.reject);

$q.all(requests).then(function(){
    // TODO
});
24
km6zla

Für diejenigen, die nach der Antwort auf den Titel der Frage suchen "AngularJS warten auf alle async-Aufrufe innerhalb von foreach finish" , hier ist ein allgemeiner Weg, dies zu erreichen, auch mit dem $ q-Service von Angle:

$scope.myArray = [1, 2, 3, 4, 5, 4, 3, 2, 1];
var loopPromises = [];
angular.forEach($scope.myArray, function (myItem) {
    var deferred = $q.defer();
    loopPromises.Push(deferred.promise);
    //sample of a long-running operation inside loop...
    setTimeout(function () {
        deferred.resolve();
        console.log('long-running operation inside forEach loop done');
    }, 2000);

});
$q.all(loopPromises).then(function () {
    console.log('forEach loop completed. Do Something after it...');
});

Hier ist eine Arbeitsprobe Probe .

10
Alfeu

Schauen Sie sich die async-Bibliothek https://github.com/caolan/async an.

Sie können also entweder alle Ihre asyn-Funktionen parallel oder seriell ausführen, und Ihr gemeinsamer Rückruf wird ausgeführt, sobald alle Funktionen abgeschlossen sind.

async.parallel([
    function(){ ... },
    function(){ ... }
], callback);

async.series([
    function(){ ... },
    function(){ ... }
]);

Ich hoffe es hilft.

3
dopplesoldner

Das können Sie einfach so machen

var jsonArray3=[];
angular.forEach($scope.jsonArray1,function(value,key){
    angular.forEach(jsonArray2,function(v,k){
        if(v.id==value.id){
            $scope.jsonArray3.Push(v);
        }
    })
})



$q.all($scope.jsonArray3).then(function(data){
   console.log("data:",data);
})
2

Sie können auch map verwenden:

var requests = cardTitles.map(function(title) {
  var deferred = $q.defer();
  Trello.post('/path', {}, deferred.resolve, deferred.reject);
  return deferred;
});

$q.all(requests).then(function() {

});

Und wenn die post-Methode bereits ein Versprechen zurückgibt:

var requests = cardTitles.map(function(title) {
  return $http.post('/path/' + title, {});
});

$q.all(requests).then(function() {

});
0
pomber