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?
推荐答案
不要使用队列和那个布尔标志,只要有一个变量存储代表所有上传的承诺.此外,您的 upload
函数不应将 Deferred 对象解析为参数,而应简单地返回一个新的承诺.
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
就变得如此简单
Then the addAnUpload
becomes as simple as
var allUploads = $q.when(); // init with resolved promise
function AddAnUpload(file) {
allUploads = allUploads.then(function() {
return upload(file);
});
}
关闭后,您不再需要 queue
来存储等待的上传.如果您希望 allUploads
始终履行,即使一个 upload
失败,您也需要从 then
回调返回一个始终履行的承诺:
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屋!