在每个

时间:2017-01-03 01:10:16

标签: angularjs ionic-framework synchronization cordova-plugins ngcordova

我在离子项目中使用ngCordova文件传输插件从网址下载图像集。这是我正在使用的代码。

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

})

问题在于程序尝试一次性下载所有内容而无需等待前一个完成。如何等待一个文件完成下载然后启动另一个?

由于

2 个答案:

答案 0 :(得分:1)

如果您想自动执行此操作(您不是第一个:How can I execute array of promises in sequential order?),您可以尝试将地址列表缩减为将执行整个链的单个Promise。

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

不要忘记让你的saveImage异步返回promise

更新:

您需要从save方法中删除then逻辑并返回download方法调用:

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

然后您可以将下载处理程序放入Promise.resolve()).then。见上文。

答案 1 :(得分: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>