2017-01-10 2 views
0

Am Schleifen über ein Array und Async-Aufrufe an eine API machen die zurückgegebenen Daten müssen mich mit einem anderen Array verschmolzen das Problem konfrontiert ist, wenn die Zusammenführung erfolgt einige der Versprechen nicht haben noch aufgelöst werden, so dass das resultierende Array nach der Zusammenführung Daten fehlt. irgendwelche Ideen, wie man das macht. (Ich bin neu bei Angular). die Anordnung am Schleifen mindestens 200 Elemente hat (ich weiß nicht, die Größe des Arrays im Voraus) bekomme ich die ID von jedem Elemente und ich nenne diesen Service:Angular JS Warten auf alle Versprechen zu lösen

for (i = 0; i < list.length; i++) { 
    service.getRawHtml(list[i].service_object_id) 
     .then(function(res){ 
      temp=htmlToArray(res); 
      htmlDataList.push(temp); 
    }, function(err){ 
     // error 
    }) 
    } 



service.getRawHtml=function (id){ 
    var defer = $q.defer(); 
     $http({ 
      method: 'GET', 
      url: 'http://wlhost:50000/'+id 
     }).success(function (response) { 
      defer.resolve(response); 
     }).error(function (data, status) { 
      console.log("Failure"); 
      defer.reject(err); 
    }); 
    return defer.promise; 
} 

Vielen Dank im Voraus.

+0

Mögliche Duplikat [Warten Sie alle Versprechen zu lösen] (http://stackoverflow.com/questions/21759361/wait-for-all-promises-to-resolve) –

+0

I Ich habe mir die Frage angeschaut, bevor ich meine beantwortete. Die Antwort, die für meine Frage vorgeschlagen wurde, ist eine ähnliche. aber es ist nicht das gleiche Szenario mit Blick auf :) – Mero

+0

Ihr Code hat keine Schleife ..? Wenn es nicht das gleiche Szenario ist, in dem du dich befindest, solltest du vielleicht mehr Code einfügen, um zu zeigen, worum es eigentlich geht. –

Antwort

2

Wie @ndoes schon sagt, kann dies mit $q.all() erfolgen, die eine Reihe von Versprechungen und Entschlüsse nimmt wenn alle von ihnen gelöst sind oder abgelehnt werden, wenn einer von ihnen abgelehnt wird.

Sie rufen die asynchrone Funktion innerhalb der for-Schleife auf, die ausgeführt wird, aber sobald alle Funktionsaufrufe durchgeführt wurden, wird der Code synchron fortgesetzt. Es wird keine magische Erwartung auf alle Versprechen geben, die es zu lösen gilt.

Sie sollten stattdessen alle Rückgabeversprechen an ein Array senden und dann $q.all() verwenden, um alle zu warten.

//Declare an array to which we push the promises 
var promises = []; 

for (i = 0; i < list.length; i++) { 
    //Call the service and push the returned promise to the array 
    promises.push(service.getRawHtml(list[i].service_object_id)); 
} 

//Await all promises 
$q.all(promises) 
    .then(function(arrayOfResults){ 
     //Use your result which will be an array of each response after 
     //it's been handled by the htmlToArray function 
    }) 
    .catch(function(err){ 
     //Handle errors 
    }); 

nahm ich die Gelegenheit, Ihren Code zur gleichen Zeit, Refactoring, da sie die deferred anti-pattern umsetzt. Da $http bereits ein Versprechen zurückgibt, müssen Sie kein neues erstellen und zurückgeben. bringen Sie es einfach sofort wie

service.getRawHtml = function (id){ 
    return $http({ 
      method: 'GET', 
      url: 'http://wlhost:50000/'+id 
     }).success(function (response) { 
      return htmlToArray(response); 
     }).error(function (data, status) { 
      console.log("Failure"); 
      $q.reject(error); 
    }); 
} 
4

Verwenden $ q.all - Vom documentation:

Kombiniert mehrere Versprechungen in ein einziges Versprechen, das gelöst wird, wenn alle Eingänge Versprechen gelöst werden.

Beispiel Nutzung:

$q.all([ 
     getPromise(), 
     getPromise(), 
     getPromise() 
    ]).then(function(value) { 
     $scope.result1 = value[0]; 
     $scope.result2 = value[1]; 
     $scope.result3 = value[2]; 
    }, function(reason) { 
     $scope.result = reason; 
    }); 
+0

Ich habe gerade meine Frage aktualisiert Ich glaube nicht, dass die Lösung, die Sie vorgeschlagen, könnte in meinem Fall funktionieren, aber ich werde es einen Versuch geben – Mero

2

nur clerify @nodes Lösung:

var promisesToWaitFor = []; 
for (i = 0; i < list.length; i++) { 
    var promis = service.getRawHtml(list[i].service_object_id) 
    promisesToWaitFor.push(promis) 
} 
$q.all(promisesToWaitFor).then(function(resultsArray) { 
    var flatten = [].concat.apply([],resultsArray); 
    temp=htmlToArray(flatten); 
    htmlDataList.push(temp); 
}, function(err) { 
    // error 
}); 
Verwandte Themen