2015-09-21 18 views
6

Qualcuno può aiutarmi con alcune promesse Angular? Ho le seguenti funzioni che dovrebbero contenere una serie di oggetti file, scorrere su di esse e caricarle ciascuna. Durante ogni iterazione, un oggetto promessa viene inviato a un array di promises. Nella mia funzione upload ho una funzione cycle con un .then() collegato, che non dovrebbe essere chiamato finché tutti gli oggetti promessi non sono stati risolti. Penso che il mio codice sia corretto, ma non funziona correttamente. Il caricamento delle immagini, ma cycle(files).then() viene chiamato immediatamente, anziché una volta risolta l'array promises.AngularJS Array of Promises

function upload(files) { 
    var uploadCount = files.length; 
    function cycle(files) { 
     var promises = []; 
     for (var i = 0; i < files.length; i++) { 
      var deferred = $q.defer(); 
      promises.push(deferred); 
      var file = files[i]; 
      Upload.upload({ 
       url: '/photos.json', 
       file: file 
      }).success(function(){ 
       $scope.progressCurrentCount += 1; 
       deferred.resolve(); 
      }); 
     }; 
     return $q.all(promises); 
    }; 

    cycle(files).then(function(result) { 
     if(uploadCount > 1) { 
      $scope.lastAction = 'uploaded ' + uploadCount + ' photos'; 
     } else { 
      $scope.lastAction = 'uploaded ' + uploadCount + ' photo'; 
     } 
     $scope.showSuccessModal = true; 
     $scope.uploading = false; 
     $scope.failedUploads = []; 
     $scope.newPhotos = { 
      token: $scope.token, 
      files: undefined 
     }; 
     photoUploadBtn.removeClass('disabled'); 
    }) 
}; 

finale codice di lavoro *

Invece di impostare var deferred = $q.defer(); spingere deferred.promise nella matrice promises, e quindi risolvendo deferred nel mio .success() callback, che non funzionava, ho appena spingo la mia funzione Upload.upload() senza la richiamata .success() in promises e quindi passare a $q.all(), che esegue tutto il sollevamento.

function upload(files) { 
    var uploadCount = files.length; 
    function cycle(files) { 
     var promises = []; 
     for (var i = 0; i < files.length; i++) { 
      var file = files[i]; 
      var promise = Upload.upload({ 
       url: '/photos.json', 
       file: file 
      }); 
      promises.push(promise); 
     }; 
     return $q.all(promises); 
    }; 

    cycle(files).then(function(result) { 
     if(uploadCount > 1) { 
      $scope.lastAction = 'uploaded ' + uploadCount + ' photos'; 
     } else { 
      $scope.lastAction = 'uploaded ' + uploadCount + ' photo'; 
     }; 
     $scope.showSuccessModal = true; 
     $scope.uploading = false; 
     $scope.failedUploads = []; 
     $scope.newPhotos = { 
      token: $scope.token, 
      files: undefined 
     }; 
     photoUploadBtn.removeClass('disabled'); 
     getPhotos(q); 
    }) 
}; 

risposta

11

Devi spingere una promessa, non una differita, alla promises matrice:

promises.push(deferred.promise); 

Aiuta se ci pensate in questo modo:

  • la promessa è una lettura -solo oggetto che si desidera restituire ai consumatori
  • posticipato è il modificatore di tale promessa di sola lettura e si desidera tenerlo per te
+0

Grazie, questa è stata la maggior parte della soluzione di cui avevo bisogno! Mi sono anche imbattuto in [questo articolo] (https://www.jonathanfielding.com/combining-promises-angular/), che mi ha fatto capire che dovrei affrontare le cose in modo leggermente diverso. Inserirò il mio codice finale nel mio post in alto. – ACIDSTEALTH