javascript - Angularjs promise 未在 Controller 中解决

标签 javascript angularjs cordova promise angular-promise

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

为了读取文件数据,Cordova/HTML5提供了一些异步方法。我正在使用 Angular 的 $q Promise 来调用这些方法。

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

但是 promise 永远不会得到解决,并且 $q.all(promises).then 中的已解决函数 block 永远不会被调用。

奇怪的是,如果我拒绝 promise 而不是使用 deferred.reject 解决它,它会调用 $q.all 的错误方法。

如何兑现 promise ?

代码如下:

//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 deferred最后一个

因此,只能解决或拒绝一个 Promise

对于 Promise.all,一次拒绝就足以拒绝 Promise.all 返回的 Promise - 但所有的 Promise 都必须由 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;
});

关于javascript - Angularjs promise 未在 Controller 中解决,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43647692/

相关文章:

javascript - 如何使用 ng-show 在 ng-repeat 中显示特定的 div?

javascript - Polymer 中的事件委托(delegate)

javascript - 获取 $q 的解决或拒绝结果

javascript - HTML 使用 JS 打印页面

javascript - 弹出窗口内容不适用于 angularjs ng-click

javascript - 带零的整数键盘

windows - npm 的漫游应用程序数据,路径太长

visual-studio - 使用 Visual Studio S2013 Apache Tools for Cordova 项目生成错误

ios - Phonegap 适用于 Android 但不适用于 iOS,错误代码

javascript - 使用对象中最新受影响的数据