9

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

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

每个fileDef文件都发送到上传函数,上传函数返回fileDef.promise并在上传后调用fileDef.resolvefileDef.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();
      })
    }
  }
}

但这似乎很糟糕。如何写得更好?

4

1 回答 1

10

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

然后addAnUpload变得如此简单

var allUploads = $q.when(); // init with resolved promise

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

关闭后,您不再需要它queue来存储等待的上传。如果你想allUploads永远履行,即使upload失败,你需要从 -callback 返回一个永远履行的承诺then

        return upload(file).then(null, function(err) {
            console.log(err, "does not matter");
        }); // fulfills with undefined in error case
于 2013-09-23T06:06:38.180 回答