1

私は、ionicプロジェクトでngCordova File Transferプラグインを使用して、URLから一連の画像をダウンロードしています。ここで私はそれを使用しているコードです。ここ各角度で同期してコール関数を呼び出す

// Save a image file in a given directory 
$scope.saveImage = function(dir,imgUrl,imageName) { 

    var url = imgUrl; 
    var targetPath = cordova.file.dataDirectory+ dir+"/" + imageName; 
    var trustHosts = true; 
    var options = {}; 

    // Download the image using cordovafiletransfer plugin 
    $cordovaFileTransfer.download(url, targetPath, options, trustHosts) 
    .then(function(result) { 
     $scope.loadedCount ++; 
     $ionicLoading.show({template : "<ion-spinner class='spinner-energized'></ion-spinner><p> Downloading pages : "+ $scope.loadedCount+" of "+ $scope.pages.length+ "</p><p>Please wait...</p><p><button class=\"button button-block button-positive\">continue in background</button></p>"}); 
     if($scope.loadedCount == $scope.pages.length) { 
      $ionicLoading.hide(); 
      $scope.showDownloadSuccessAlert = function() { 
       var alertPopup = $ionicPopup.alert({ 
        title: 'Success!', 
        template: "Your magazine successfully downloaded. You can view it on Downloads!" 
       }); 
      }; 
      $scope.showDownloadSuccessAlert(); 
     } 
    }, function(err) { 
     alert(JSON.stringify(err)); 
    }, function (progress) { 
     if($scope.loadedCount > 80) { 
     } 
    }); 
}; 

// Download the current magazine 
$scope.downloadMagazine = function() { 
    if($rootScope.user.user_id == undefined) { 
     $scope.showLoginAlert = function() { 
       var alertPopup = $ionicPopup.alert({ 
        title: 'Oops!', 
        template: "Your must login to download magazines" 
       }); 
      }; 
     $scope.showLoginAlert(); 
     return; 
    } 

    document.addEventListener('deviceready', function() { 

     var dirName = $rootScope.currentIssue.slug+'_VOL_'+$rootScope.currentIssue.vol+'_ISU_'+$rootScope.currentIssue.issue; 

     // First create the directory 
     $cordovaFile.createDir(cordova.file.dataDirectory, dirName, false) 
     .then(function (success) { 
      var count = 1; 
      $scope.loadedCount = 0; 
      angular.forEach($scope.pages, function(value, key) { 
       var imgName = count+".png"; 
       $scope.saveImage(dirName,value.link,imgName); // Then save images one by one to the created directory. 
       count++; 
      }); 

     }, function (error) { 
      // Directory already exists means that the magazine is already downloaded. 
      $scope.showDownloadedAlert = function() { 
       var alertPopup = $ionicPopup.alert({ 
        title: 'Why worry!', 
        template: "Your have already downloaded this magazine. You can view it on downloads" 
       }); 
      }; 
      $scope.showDownloadedAlert(); 
     }); 

    }, false); 
}; 

})

問題は、プログラムが終了する前のものを待たずに、一度にすべてをダウンロードしようとしていることです。 1つのファイルがダウンロードを完了してからもう一方のファイルを開始するまで待つ方法

おかげ

答えて

1

あなたは(あなたが最初のものじゃない。How can I execute array of promises in sequential order?)自動的にそれをしたい場合は、チェーン全体を行います単一の約束にアドレスのリストを減らしてみてください。

$scope.pages.reduce(function (curr,next) { 
     return curr.then(function(){    
      return $scope.saveImage(dirName, curr.link, imgName); 
     }); 
    }, Promise.resolve()).then(function(result) { 

     $ionicLoading.show({template : "<ion-spinner class='spinner-energized'></ion-spinner><p> Downloading pages : "+ $scope.loadedCount+" of "+ $scope.pages.length+ "</p><p>Please wait...</p><p><button class=\"button button-block button-positive\">continue in background</button></p>"}); 
     if($scope.loadedCount == $scope.pages.length) { 
      $ionicLoading.hide(); 
      $scope.showDownloadSuccessAlert = function() { 
       var alertPopup = $ionicPopup.alert({ 
       title: 'Success!', 
       template: "Your magazine successfully downloaded. You can view it on Downloads!" 
      }); 
     }; 
     $scope.showDownloadSuccessAlert(); 
    } 
    }); 

そしてpromise返すあなたsaveImage非同期を作ることを忘れないでください。

UPDATE:

あなたの方法を保存し、downloadメソッド呼び出しを返すから、その後のロジックを削除する必要があります。

return $cordovaFileTransfer.download(url, targetPath, options, trustHosts).promise; 

次にあなたがPromise.resolve()).thenにあなたのダウンロードハンドラを置くことができます。上記を参照。

+0

あなたは 'promise'を返し、あなたの' saveImage'非同期を作る」説明してくださいでした申し訳ありませんが、私は初心者だ –

+0

あなたはsaveImageのコードを投稿することができますか。? – Yaser

+0

コードが更新されました。見てください –

0

あなたの約束を繋ぐ以外の方法はありません。ここでは例を示します。

angular.module('app', []) 
 
    .service('fakeDownloadService', function($timeout) { 
 
    this.download = (file) => $timeout(() => file, 100); 
 
    return this; 
 
    }) 
 
    .run(function($rootScope, $q, fakeDownloadService) { 
 
    var listOfFiles = []; 
 
    for (var i = 0; i < 10; i++) 
 
     listOfFiles.push('file' + i); 
 
    $rootScope.log = []; 
 
    $rootScope.download =() => { 
 
     listOfFiles 
 
     .reduce((prev, curr) => { 
 
      return prev.then((result) => { 
 
      if(result) 
 
      $rootScope.log.push(result + ' downloaded'); 
 
      return fakeDownloadService.download(curr); 
 
      }); 
 
     }, $q.resolve()) 
 
     .then(() => $rootScope.log.push('all done')); 
 
    }; 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script> 
 
<div ng-app="app"> 
 
    <button ng-click="download()">Start</button> 
 
    <div>Log:</div> 
 
    <ul> 
 
    <li ng-repeat="entry in log track by $index"> 
 
     {{entry}} 
 
    </li> 
 
    </ul> 
 
</div>

関連する問題