簡體   English   中英

AngularJS承諾不會在控制器中解決

[英]Angularjs promise not being resolved in controller

我有一個使用angular和cordova的離子(v1)項目。 我遍歷文件名數組,並將每個文件數據附加到FormData對象中,該對象必須上傳到服務器。

為了讀取文件數據, Cordova/HTML5提供了一些異步的方法。 我正在使用angular的$q promise來調用這些方法。

然后,我想使用$q.all等到所有的諾言都解決$q.all開始上傳。

但是承諾永遠不會被解決,並且$q.all(promises).then的已解決功能塊也不會被調用。

奇怪的是,如果我拒絕了promise,而不是用deferred.reject解決它,它將調用$q.all的錯誤方法。

我如何履行諾言?

這是代碼:

//Inside a controller
var promises = [];

for (var key in $scope.rArray) {
      if ($scope.rArray.hasOwnProperty(key)) {
          var deferred = $q.defer();
          var tmpFile = $scope.rArray[key];

          var i  = cordova.file.externalRootDirectory + "/" + tmpFile;

          window.resolveLocalFileSystemURL(i, function(fileEntry) {
              fileEntry.file(function(file) {
                  var reader = new FileReader();
                  reader.onloadend = function(e) {
                      console.log('onloadend callled');
                      var fileBlob = new Blob([this.result], { type:file.type});
                      fd.append('file', fileBlob,file.name);
                      deferred.resolve(fd); //if reject here it is reflected
                      //$rootScope.$apply(). tried this too

                  };
                  reader.readAsArrayBuffer(file);

              }, function(e) {
                  console.log('error getting file', e);
                  deferred.reject(e);
              });
          }, function(e) {
              console.log('Error resolving fs url', e);
              deferred.reject(e);
          });

          promises.push(deferred.promise);
      }
    };

    $q.all(promises).then(function (dataAr) {
      console.log('promises resolved..'); //NEVER CALLED
      var request = new XMLHttpRequest();
      request.open('POST', ENV.baseUrl+"/st/st");
      request.send(fd);
    }, function errorfn(err) {
      console.error(JSON.stringify(err));
    })

問題是,在調用任何resolveLocalFileSystemURL函數的任何回調時, var deferredvar deferred最后一個 resolveLocalFileSystemURL

因此,只有一個諾言可以被解決或拒絕

使用Promise.all,一個拒絕就足以拒絕Promise.all返回的Promise-但所有的Promise.all都必須解決Promise.all才能解決

我最初是在您的代碼中使用閉包的想法-但是使用通用的JS方法似乎是一個更好的解決方案-Object.keys和Array#map

var promises = Object.keys($scope.rArray).map(function(key) {
    var tmpFile = $scope.rArray[key];
    var deferred = $q.defer();
    var i  = cordova.file.externalRootDirectory + "/" + tmpFile;
    window.resolveLocalFileSystemURL(i, function(fileEntry) {
        fileEntry.file(function(file) {
            var reader = new FileReader();
            reader.onloadend = function(e) {
                console.log('onloadend callled');
                var fileBlob = new Blob([this.result], { type:file.type});
                fd.append('file', fileBlob,file.name);
                deferred.resolve(fd); //if reject here it is reflected
            };
            reader.readAsArrayBuffer(file);
        }, function(e) {
            console.log('error getting file', e);
            deferred.reject(e);
        });
    }, function(e) {
        console.log('Error resolving fs url', e);
        deferred.reject(e);
    });

    return deferred.promise;
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM