【问题标题】:AngularJS $q. Deferred queueAngularJS $q。延迟队列
【发布时间】:2013-09-27 09:23:50
【问题描述】:

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

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

每个 fileDeffile 发送到上传函数,返回 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();
      })
    }
  }
}

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

【问题讨论】:

  • 你为什么不连锁承诺呢??
  • 因为我现在没有队列大小
  • 上传失败会怎样?这不重要吗?
  • 参见示例:github.com/tamtakoe/oi.file/blob/master/oi.file.js#L251

标签: angularjs promise deferred q


【解决方案1】:

不要使用队列和布尔标志,只需使用一个变量来存储代表所有上传的承诺。此外,您的 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-callback 返回一个始终实现的承诺:

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

【讨论】:

  • 参见示例:github.com/tamtakoe/oi.file/blob/master/oi.file.js#L251 我不能在队列中使用 promise,因为我需要在传输函数中拒绝和解析
  • @tamtakoe:我看不出有什么问题?
  • 没问题。我只认为我的代码不美观,因为我使用了延迟数组而不是承诺数组
  • 使用 deferreds(内部)并没有错,它们就像 Promise 一样工作。
  • 请注意 $q.defer().resolve() 不会返回承诺(至少在当前版本的 AngularJS 上不会),因此 allUploads 对象必须分三步构建; var queueDeferred = $q.defer(); var queue = queueDeferred.promise; queueDeferred.resolve();
猜你喜欢
  • 2013-09-11
  • 1970-01-01
  • 1970-01-01
  • 2018-07-25
  • 2015-06-11
  • 1970-01-01
  • 1970-01-01
  • 2015-09-30
  • 2014-06-10
相关资源
最近更新 更多