如何在循环中链接异步ajax函数 [英] How to chain an async ajax function in a loop
问题描述
我想链接一个异步ajax函数,该函数在一个循环中被多次调用.为什么?因为该功能是上传文件,但我希望它顺序上传文件,而不是一次上传所有文件.我不想使用async false,因为我希望在DOM上更新进度.
I would like to chain an asynchronous ajax function that is called several times within a loop. Why? Because that function is to upload files but I want it to serially upload files rather than uploading all of them at once. I don't want to use async false because I want the progress updated on the DOM.
for (var i = 0; i < files.length; i++) {
var fd = new FormData();
fd.append('file', files[i]);
fd.append('galleryid', galleryid);
sendFileToServer(fd); //chain this function call
}
function sendFileToServer(formData)
{
var uploadURL ="includes/ajax/images/uploadImagePage.php"; //Upload URL
var extraData ={}; //Extra Data.
return jqXHR=$.ajax({
xhr: function() {
var xhrobj = $.ajaxSettings.xhr();
if (xhrobj.upload) {
xhrobj.upload.addEventListener('progress', function(event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
//Set progress
$('#uploadImageResponse').html(percent+'%');
}, false);
}
return xhrobj;
},
url: uploadURL,
type: "POST",
async:true,
contentType:false,
processData: false,
cache: false,
data: formData,
success: function(data){
status.setProgress('Upload completed. 100%.');
}
});
}
我不明白jquery延迟对象的工作方式.
I don't understand how jquery deferred objects work.
推荐答案
有很多不同的方法可以序列化多个请求,例如这样.这是一种使用手动迭代而不是for
循环的方法,因此只有在前一个迭代完成后才前进到下一个迭代.
There are a number of different approaches for serializing multiple requests like this. Here's one way that uses a manual iteration instead of the for
loop so you only advance to the next iteration when the previous one has completed.
手动迭代
function sendAllFiles(files) {
var index = 0;
function next() {
var fd;
if (index < files.length) {
fd = new FormData();
fd.append('file', files[index]);
fd.append('galleryid', galleryid);
++index;
// send this file and when done, do the next iteration
sendFileToServer(fd).then(next);
} else {
// all files are done now
}
}
// start the first iteration
next();
}
使用.reduce()
Chained promises using .reduce()
而且,这是使用.reduce()
和链接的诺言的另一种设计模式:
And, here's a different design pattern using .reduce()
and chained promises:
files.reduce(function(p, item) {
return p.then(function() {
var fd = new FormData();
fd.append('file', item);
fd.append('galleryid', galleryid);
return sendFileToServer(fd);
});
}, $.Deferred().resolve()).then(function() {
// all files are done now
});
这篇关于如何在循环中链接异步ajax函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!