Angular JS promise / defer:使用框架Quickblox,如何上传图像,然后将公共URL上传到自定义对象

时间:2014-08-18 20:12:16

标签: javascript angularjs quickblox angular-promise

我正在创建一个应用程序,我希望用户能够上传5张自己的图像。

我正在使用后端即服务(Quickblox),这需要我创建blob文件并单独上传它们。完成每次上传后,我会通过该图像的amazon aws url成功回调。

然后,我需要将所有亚马逊aws网址再次上传回Quickblox,将个人资料与特定网址绑定。 (如果您熟悉Quickblox,我有一个自定义对象,其中有5个字段作为图像网址。)

我不确定在角度js中执行此操作的正确方法。

我目前正在链接5张承诺上传每张图片,第6张承诺上传亚马逊网址一次可用。我的问题是,最后的承诺是在收到所有亚马逊aws网址之前解雇。有没有办法更恰当地做到这一点?我似乎误解了承诺和推迟......

这是我的代码:

function QBCreateAndUpload(q,scope,i){

// async call to post image
QB.content.createAndUpload({'file':scope.image_blobs[i],'name':"profilepics.jpg", 'type':"image/jpeg", 'public': true },function(e,r){
        if(e){
          return q.reject("error");
        } else {
          scope.amazon_urls[i]= "http://qbprod.s3.amazonaws.com/" + r.uid;
          return scope.amazon_urls;
        }
      });
}

var deferred = $q.defer();
var promise =   
deferred.promise.then(QBCreateAndUpload($q,$scope,0))
.then(QBCreateAndUpload($q,$scope,1))
.then(QBCreateAndUpload($q,$scope,2))
.then(QBCreateAndUpload($q,$scope,3))
.then(QBCreateAndUpload($q,$scope,4))
.then(function(result){
    //async call to upload amazon urls
    var data = {
      _id: principal.data_object_id,
      image1: results[0],
      image2: results[1],
      image3: results[2],
      image4: results[3],
      image5: results[4]
    }


    QB.data.update(className,data,function(e,r){
        if (e){
        } else {
          console.log(r);
          return "all uploaded";
        }
    });

});
deferred.resolve();

1 个答案:

答案 0 :(得分:1)

您的QBCreateAndUpload函数没有以正确的方式解析/拒绝承诺,这意味着您的每个函数都不可靠。在我看来,你不太了解承诺如何与一般合作。

我试图保留大部分功能并保持简单。通常你应该避免绕过范围

function QBCreateAndUpload(deferred, scope, i) {
  QB.content.createAndUpload({'file':scope.image_blobs[i],'name':"profilepics.jpg", 'type':"image/jpeg", 'public': true }, function(e,r) 
    {
      if (e) 
      {
        deferred.reject(e);
      } 
      else 
      {
        scope.amazon_urls[i] = "http://qbprod.s3.amazonaws.com/" + r.uid;
        deferred.resolve("http://qbprod.s3.amazonaws.com/" + r.uid);
      }
  });
  // the promise is immediately returned
  // the reject() and resolve() functions are called when the async call finishes
  return deferred.promise;
}

// we will use this array of promises to keep track of our progress
var promises = [];

for (var i = 0; i < 5; i++) {
  var deferred = $q.defer();
  // we pass the deferred object into the function
  // the function will execute reject() or resolve() 
  // as soon as the async function finsishes
  var promise = QBCreateAndUpload(deferred, scope, i);
  // we store the promise object that the QBCreateAndUpload function
  // immediately returns into our array
  promises.push(promise);
}

// the all function creates a new promise that will resolve as soon as all
// promises in our promises array have resolved; if even one fails
// the all promise fails as well
$q.all(promises).then(function (results) {
  // the results object contains all objects that were passed when the promises 
  // were resolved; this seems a little pointless since you passed the scope into 
  // the function which would contain the image URLs anyway
  var data = {
    _id: principal.data_object_id,
    image1: results[0],
    image2: results[1],
    image3: results[2],
    image4: results[3],
    image5: results[4]
  }

  QB.data.update(className,data,function(e,r){
    if (e)
    {
    } 
    else 
    {
      console.log(r);
      // return "all uploaded";
      // the return is absolutely pointless since you were not synchronous
      // you would need another promise / callback at this point
    }
}, function (error){
  console.log(error);
});