$ q.all没有按预期工作?

时间:2014-08-19 02:19:57

标签: angularjs

有人可以向我解释为什么我的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;
}

1 个答案:

答案 0 :(得分:1)

经过很多困难后,事实证明q.all在我的第一次承诺被解雇后正在解雇。

然而,自从我把第一套承诺链接起来后,我期待q.all在第二套承诺之后开火。

为了让他们在第一组之后开火,我必须为第一组创建一个承诺数组,然后使用

.then(function(){$q.all(second_set_of_promises).then(third_final_set_of_promises)});

这样,第三组承诺仅在第二组完成后触发,第二组仅在第一组完成时触发。