Javascript 控制器中未解析Angularjs承诺

Javascript 控制器中未解析Angularjs承诺,javascript,angularjs,cordova,promise,angular-promise,Javascript,Angularjs,Cordova,Promise,Angular Promise,我有一个使用angular和cordova的ionic(v1)项目。 我在一个文件名数组上循环,并将每个文件数据附加到FormData对象中,该对象必须上载到服务器 对于读取文件数据,Cordova/HTML5提供了一些异步方法。我使用angular的$q承诺调用这些方法 然后我想使用$q.all等待所有承诺得到解决并开始上传 但是承诺永远不会得到解决,并且$q.all(承诺)中已解决的功能块也永远不会被调用 奇怪的是,如果我拒绝承诺,而不是用延迟解决它。拒绝它调用$q.all的错误方法 我如何

我有一个使用angular和cordova的ionic(v1)项目。 我在一个文件名数组上循环,并将每个文件数据附加到
FormData
对象中,该对象必须上载到服务器

对于读取文件数据,
Cordova/HTML5
提供了一些异步方法。我使用angular的
$q
承诺调用这些方法

然后我想使用
$q.all
等待所有承诺得到解决并开始上传

但是承诺永远不会得到解决,并且
$q.all(承诺)中已解决的功能块也永远不会被调用

奇怪的是,如果我拒绝承诺,而不是用
延迟解决它。拒绝
它调用
$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));
    })

问题在于,
var deferred
是调用任何
resolveLocalFileSystemURL
函数的任何回调时的最后一个

因此,只有一个承诺可以被解决或拒绝

对于Promise.all,一次拒绝就足以拒绝Promise.all返回的承诺,但所有承诺都必须为Promise.all解决

我最初在代码中考虑了闭包的概念,但使用普通的JS方法似乎是更好的解决方案——Object.keys和Array#map


从您的描述来看,似乎并不是所有承诺都得到了解决-这就是为什么q.all永远不会继续-当一个承诺拒绝时,q.all拒绝,而不管其他承诺的状态如何
var deferred=$q.deferred()是问题所在。。。
deferred
的值将是每个
deferred.resolve
调用的最后一个值-因此只有最后一个值可以被解析!但是我很困惑。你能解释一下我代码中的控制流程吗。正如您提到的,它总是使用最后一个延迟来解决问题,它不应该使用最初调用它的延迟吗。我的意思是异步回调的作用域应该不同?
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;
});