2015-09-21 3 views
6

Kann mir jemand mit einigen Winkelversprechen helfen? Ich habe die folgenden Funktionen, die ein Array von Dateiobjekten aufnehmen, über sie iterieren und jedes hochladen sollten. Während jeder Iteration wird ein Zusicherungsobjekt an ein Array von promises übergeben. Innerhalb meiner upload Funktion habe ich eine cycle Funktion mit einer verbunden, die nicht aufgerufen werden sollte, bis alle Versprechen Objekte aufgelöst haben. Ich denke mein Code sieht korrekt aus, aber es funktioniert nicht richtig. Die Bilder werden hochgeladen, aber cycle(files).then() wird sofort aufgerufen, anstatt einmal das promises Array zu verrechnen.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'); 
    }) 
}; 

Abschlussarbeits Code *

Anstatt Einstellung var deferred = $q.defer();deferred.promise in die promises Array schieben, und die Lösung dann deferred in meinem .success() Rückruf, der nicht funktioniert, schiebe ich nur meine Upload.upload() Funktion ohne die .success() Rückruf in promises, und dann diese an $q.all() übergeben, die alle Aufhebung tut.

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); 
    }) 
}; 

Antwort

11

Sie müssen ein Versprechen schieben, kein latenten, auf die promises Array:

promises.push(deferred.promise); 

Es hilft, wenn man darüber so denken:

  • das Versprechen ist ein Lese Nur das Objekt, das Sie an die Konsumenten zurückgeben möchten
  • Deferred ist der Modifizierer dieses schreibgeschützten Versprechens, und Sie möchten es für sich behalten
+0

Danke, das war die meiste Lösung, die ich brauchte! Ich stieß auch auf [diesen Artikel] (https://www.jonathanfielding.com/combining-promises-angular/), was mir klar machte, dass ich etwas anders angehen sollte. Ich werde meinen letzten Code in meinem Beitrag oben setzen. – ACIDSTEALTH