Angular цепочка обещаний из цикла foreach

У меня есть массив файлов фотографий, которые необходимо загрузить в облачное хранилище Azure, и я использую цикл foreach для вызова загрузки, как показано ниже:

$scope.savetemplate = function () { 
     var imagePathsArray = [];

     $scope.filesimage = [];
     $scope.filesimage.push($scope.file1);
     $scope.filesimage.push($scope.file2);
     $scope.filesimage.push($scope.file3);


    for (var i in $scope.filesimage) {
        $scope.upload($scope.filesimage[i]);
    }


    $scope.data.Images = imagePathsArray ;

     $http({
              //after finish uploads i need to post the paths 
              //of all images to save into database
     })
 };


$scope.upload = function (file) {
  Upload.upload({
       url: '/uploadImage',
       data: { file: file }
    }).then(function (resp) {
       imagePathsArray.push(resp.data);

    })
};

resp.data возвращает путь к лазурному хранилищу, и мне нужно вставить пути в imagePathsArray

Как я могу использовать Angular Promise для ожидания завершения загрузки всех файлов и сохранения всех путей в imagePathsArray, поэтому я могу продолжить

 $scope.data.Images = imagePathsArray ;

чтобы я мог получить пути в массиве и выполнить сообщение $http?


person Mentos    schedule 18.11.2015    source источник


Ответы (2)


Вы можете сделать это с помощью $q.all.

var promises = [];
for (var i in $scope.filesimage) {
    promises.push(upload($scope.filesimage[i]));
}
$q.all(promises).then(function() {
    $scope.data.Images = imagePathsArray ;

    $http.post({
          //after finish uploads i need to post the paths 
          //of all images to save into database
    });
});

function upload(file) {
    return Upload.upload({
       url: '/uploadImage',
       data: { file: file }
    }).then(function (resp) {
       imagePathsArray.push(resp.data);
    })
};
person Michael    schedule 18.11.2015
comment
Привет, Майкл! Ваше решение работает как шарм! Спасибо! - person Mentos; 18.11.2015

В успешном обратном вызове функции загрузки после нажатия пути:

imagePathsArray.push(resp.data);
if(imagePathsArray.length == $scope.filesimage.length){
  pushtoDatabase();
}

Внутри pushtoDatabase позвоните в $http({ .... });

ПРИМЕЧАНИЕ. Вы можете рассмотреть вероятность сбоя загрузки. В этом случае вы можете обойти это, используя счетчик неудачных файлов, скажем, failCounter , а затем внутри if проверьте условие

if ((imagePathsArray.length + failCounter) == $scope.filesimage.length){....}

person Sujeet Jaiswal    schedule 18.11.2015