有人可以向我解释为什么我的q.all无效吗?
我有5个承诺,将图像下载到blob文件。我有另外5个承诺,将这些blob上传到我使用的服务器。我使用后端即服务Quickblox,因此成功上传的回调提供了Amazon AWS url链接。我需要获取所有这些链接并将它们上传到我的服务器,以便我知道哪个用户与哪些图像相关联。
5次下载和上传似乎有效,但上传到网址无效。在上传函数中发生每个解析之前,回调会将$scope.amazon_urls
=设置为提供的回调网址。因此,当Q.all.runs时,我希望所有$scope.amazon_urls
都存在。然而事实并非如此。发生了什么事?
功能顺序是:1)
以下是上传网址的功能。我已经评论了我认为导致问题的部分。
function uploadURLs(scope,principal){
QB.data.list(className,{user_id:principal.user_id},function(err,res){
if (err){
console.log(err);
return err;
} else {
console.log(res)
var data = {
_id: res.items[0]._id,
image1: scope.amazon_urls[0], // Accessing these values should all be set after q.all
image2: scope.amazon_urls[1], // A null value indicates that
image3: scope.amazon_urls[2], //the callback function has not set it yet
image4: scope.amazon_urls[3], // however this function should occur after q.all
image5: scope.amazon_urls[4] // so shouldn't this all be set already?
}
QB.data.update(className,data,function(e,r){
if (e){
console.log(e);
return e;
} else {
console.log(r);
return r;
}
});
}
});
}
这是执行下载/上传承诺的按钮,并将它们推送到数组$scope.promises
$scope.selectPictureForProfile = function(t){
var deferred = $q.defer();
var qbdeferred = $q.defer();
var promise = xhrPromise(deferred,t.photo,$scope,$scope.currently_selected).then(function(blob){
QBCreateAndUploadPromise(qbdeferred,$scope,$scope.currently_selected,blob);
});
$scope.promises.push(promise);
}
这是运行q.all的按钮。一切都解决了,
$scope.save_photos = function(){
$q.all($scope.promises).then(function(response){
uploadURLs($scope,principal); // this seems to execute before last promise
});
}
以下是下载图片的功能......
function xhrPromise(deferred,url,scope,i){
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var myBlob = this.response;
scope.image_blobs[i] = myBlob;
deferred.resolve(myBlob);
} else {
deferred.reject("");
}
};
xhr.send();
return deferred.promise;
}
以下是上传图片的功能......
function QBCreateAndUploadPromise(deferred,scope,i,blob){
QB.content.createAndUpload({'file':blob,'name':"profilepics.jpg", 'type':"image/jpeg", 'public': true },function(e,r){
if(e){
deferred.reject("error");
} else {
scope.amazon_urls[i]= "http://qbprod.s3.amazonaws.com/" + r.uid;
deferred.resolve("http://qbprod.s3.amazonaws.com/"+ r.uid);
}
});
return deferred.promise;
}
答案 0 :(得分:1)
经过很多困难后,事实证明q.all
在我的第一次承诺被解雇后正在解雇。
然而,自从我把第一套承诺链接起来后,我期待q.all
在第二套承诺之后开火。
为了让他们在第一组之后开火,我必须为第一组创建一个承诺数组,然后使用
.then(function(){$q.all(second_set_of_promises).then(third_final_set_of_promises)});
这样,第三组承诺仅在第二组完成后触发,第二组仅在第一组完成时触发。