AngularJS $ q。延迟队列

时间:2013-09-22 10:50:02

标签: angularjs promise deferred q

我有数组(例如,它是文件队列):

[{deferred: fileDef, data: file}, {...}, ...]

每个 fileDef 文件发送到上传功能,该功能返回 fileDef.promise 并调用 fileDef.resolve 或上传后 fileDef.reject

我想按顺序上传文件:加载上一个文件后下一个文件上传。

现在我用

var queue = [];
var uploading = false;

//file input callback call each time the user selects files
function addAndUpload (file) {

  queue.push({deferred: $q.defer(), data: file});

  if (!uploading) recurceQueue();

  function recurceQueue () {
    if (queue.length) {
      uploading = true;
      var fileObj = queue.shift();
      upload(fileObj.deferred, fileObj.data);

      fileObj.deferred.promise.finally(function () {
        uploading = false;
        recurceQueue();
      })
    }
  }
}

但似乎很糟糕。怎么写得更好?

1 个答案:

答案 0 :(得分:10)

不要使用队列和那个布尔标志,只需要一个存储代表所有上传的promise的变量。此外,您的upload函数不应将Deferred对象作为参数进行解析,而只需返回新的承诺。

然后addAnUpload变得像

一样简单
var allUploads = $q.when(); // init with resolved promise

function AddAnUpload(file) {
    allUploads = allUploads.then(function() {
        return upload(file);
    });
}

使用闭包,您不需要queue来存储等待的上传。如果您希望allUploads始终满足,即使一个upload失败,您也需要从then - 回调中返回一个始终履行的承诺:

        return upload(file).then(null, function(err) {
            console.log(err, "does not matter");
        }); // fulfills with undefined in error case