我有一个使用 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/