AngularJS $ q.递延队列 [英] AngularJS $q. Deferred queue
问题描述
我有数组(例如,它是文件队列):
I have array (f.e. it is queue of files):
[{deferred: fileDef, data: file}, {...}, ...]
每个 fileDef 和 file 发送到上传函数,这些函数返回 fileDef.promise 并调用 fileDef.resolve 或 fileDef.reject 上传后.
Each fileDef and file send to upload function which return fileDef.promise and call fileDef.resolve or fileDef.reject after uploading.
我要按顺序上传文件:加载上一个文件后上传下一个文件.
I want upload files in order: next file upload after previous file is loaded.
现在我用
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();
})
}
}
}
但这似乎很糟糕.如何写得更好?
But it seems bad. How to write better?
推荐答案
不要使用队列和该布尔值标志,只需使用一个变量来存储表示所有上载的Promise.另外,您的upload
函数不应将Deferred对象作为参数来解析,而只需 return 一个新的Promise.
Don't use a queue and that boolean flag, just have one variable storing a promise representing all uploads. Also, your upload
function should not take a Deferred object to resolve as an argument, but simply return a new promise.
然后addAnUpload
变得简单
var allUploads = $q.when(); // init with resolved promise
function AddAnUpload(file) {
allUploads = allUploads.then(function() {
return upload(file);
});
}
关闭后,您不再需要queue
来存储等待上传的内容.如果您希望allUploads
始终履行,即使一个upload
失败,您也需要从then
-callback中返回一个始终履行的承诺:
With the closure, you don't need that queue
to store the waiting uploads any more. If you want allUploads
to fulfill always, even if one upload
fails, you need to return an always-fulfilling promise from the then
-callback:
return upload(file).then(null, function(err) {
console.log(err, "does not matter");
}); // fulfills with undefined in error case
这篇关于AngularJS $ q.递延队列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!