我有数组(即它是文件队列(:
[{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();
})
}
}
}
但这似乎很糟糕。如何写得更好?
不要使用队列和布尔标志,只需有一个变量存储代表所有上传的承诺。此外,您的 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