我有一个使用Angular和Cordova的离子(V1(项目。我正在循环浏览一系列文件名,并在FormData
对象中附加每个文件数据,必须将其上传到服务器。
用于读取文件数据,Cordova/HTML5
提供了一些异步的方法。我正在使用Angular的$q
承诺来调用这些方法。
然后,我想使用$q.all
等待所有承诺解决并开始上传。
,但承诺永远无法解决,并且$q.all(promises).then
内的已解决功能块永远不会被调用。
奇怪的是,如果我拒绝承诺而不是使用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));
})
问题是var deferred
是最后一个,到任何 resolveLocalFileSystemURL
函数的任何回调时都称为
所以,只能解决或拒绝一个诺言
有了承诺。所有拒绝足以拒绝承诺所归还的承诺 - 但所有诺言都必须决心承诺。
我最初是在您的代码中关闭的想法 - 但是使用常见的JS方法似乎是一个更好的解决方案-Oboce.coblect.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;
});