我正在将文档列表上载到服务器,并且对于每个文档,我都会启动ajax请求,但是请求的数量是未知的(取决于要上载的文档的数量)。上传所有文档(完成所有ajax请求)后,如何向用户显示消息。
$.each(files,function(idx,elm){
let formData = new FormData();
let ID = '_' + Math.random().toString(36).substr(2, 9);
formData.append('document_id', ID);
formData.append('file-doc', elm);
$.ajax({
url: "http://127.0.0.1:5000/add_multiple_docs",
type: 'POST',
data: formData,
cache: false,
contentType: false,
processData: false,
beforeSend: function (xhr, settings) {
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
},
success: function (data) {
alert(data);
},
failure: function (request) {
console.log(request);
},
error: function (jqXHR, exception) {
console.log("error add document");
let msg = '';
if (jqXHR.status === 0) {
msg = 'Not connect.\n Verify Network.';
} else if (jqXHR.status === 404) {
msg = 'Requested page not found. [404]';
} else if (jqXHR.status === 500) {
msg = 'Internal Server Error [500].';
} else if (exception === 'parsererror') {
msg = 'Requested JSON parse failed.';
} else if (exception === 'timeout') {
msg = 'Time out error.';
} else if (exception === 'abort') {
msg = 'Ajax request aborted.';
} else {
msg = 'Uncaught Error.\n' + jqXHR.responseText;
}
console.log(msg)
}
});
});
}
答案 0 :(得分:1)
要实现所需的功能,可以将从$.ajax()
返回的所有jqXHR对象放在一个数组中,该数组可以apply()
到$.when()
。在所有这些承诺都解决之后,您便可以执行所需的任何逻辑。试试这个:
var promises = files.map(function(elm) {
// setup formData...
return $.ajax({
url: "http://127.0.0.1:5000/add_multiple_docs",
// ajax settings...
});
});
$.when.apply($, promises).done(function() {
console.log('all requests complete, do something here...');
});
然而,绝对值得注意的是,在循环中发送AJAX请求不是可扩展的模式。将所有文件和相关数据聚合到一个AJAX请求中,然后在服务器上处理一次,将是一个更好的主意。
答案 1 :(得分:1)
首先,您知道要上传多少个文件,所以您知道要执行多少个ajax请求。 (每个文件1个请求)
因此,在您的$.each()
被解雇之前,您的大小为files
let count = $(files).size();
$.each(files,function(idx,elm){
/*your code with requests*/
}
现在,在每个ajax请求均未触发后,递减count
。在success
和failure
方法中递减,因为无论成功与否,它都不会消光。并检查是否count === 0
。如果它是0,那么您知道所有ajax都已完成。
$.ajax({
/*your other settings*/
success: function (data) {
alert(data);
count--;
doSomething(count);
},
failure: function (request) {
console.log(request);
count--;
doSomething(count);
},
});
function doSomething(count){
if(count === 0){
/*stuff you wannna do after all ajax requests are done*/
}
}
我现在还没有做那么多ajax,所以我不确定failure
上是否也触发了error
,但是如果不能,还可以添加count--
和if也会出错。
答案 2 :(得分:0)
一个非常有趣的问题。
当尝试从youtube API获取数据时,我遇到了类似的问题,该API仅返回最多50个项目的结果集。
为解决此问题,我使用了一个接受回调的递归函数,在基本情况下(在我的情况下,当没有nextPageToken时),我调用了回调函数。
在$ .ajax请求的成功处理程序中触发了递归。
function fetchVideos(nextPageToken, callback) {
if (nextPageToken === null || nextPageToken === undefined) {
callback(null);
return;
}
$.ajax(requestURI + `&pageToken=${nextPageToken}`, {
success: (data) => {
// use data somehow?
fetchVideos(data.nextPageToken, callback);
},
error: (err) => {
callback(err);
}
})
}
fetchVideos("", (err) => {
if (err) {
console.log(err.responseJSON);
return;
}
updateUI();
})
当响应中不再有nextPageToken时,它将触发if语句。我认为它可以同步吗?因为我需要nextPageToken才能执行下一个请求。
我知道这不是最适合您的情况,但我是根据标题(即我进入此页面的方式)回答的:)