我在 for
循环中进行 AJAX 调用,我想等到所有调用都完成后再做某事。
我正在尝试使用 promises,但我缺少一些东西,因为它不起作用。如果触发错误,我的 when
调用会立即触发,而我不想这样做。我想等到所有调用都完成,无论是成功还是错误。
当所有调用完成后,我想要成功的条目数和错误数组。
这是我的代码:
for (var i = 0; i < resp.propertiesList.length; i++) {
var documentToSend = {
indexName: indexName,
type: type,
jsonContent: blabla
};
var promise = _TOOLS.Ajax({
type: 'POST',
url: urlTest,
data: documentToSend,
contentType: 'application/x-www-form-urlencoded',
dataType: 'json',
success: function (dataResponse) {
numberOfEntriesSuccess++;
},
error: function (xhr, ajaxOptions, errorThrown) {
var errorResponse = JSON.parse(xhr.responseText);
errorsList.push(errorResponse.ExceptionMessage + ". Skipping line.");
}
});
promises.push(promise);
}
//When all ajax calls are finished, load report page and display informations
$.when.apply($, promises).done(function() {
console.log("DONE " + promises.length);
console.log(errorsList);
})
我尝试了 .done
、.then
、.always
,但它们都没有在我希望时触发。
我在 Internet 上阅读了很多关于 promises 的内容,但我确实遗漏了一些东西,这让我发疯。
感谢您的帮助!
最佳答案
我发现处理这些事情最简单的方法是跟踪对象或数组中每个异步调用的状态。每次调用完成时,将其标记为已完成并检查是否还有运行。您甚至可以只向您的对象添加一个 bool 值以检查 asyncIsBusy
或 ajaxStatus
的属性。
我在这里假设 indexName
和 type
来自 resp.propertiesList
(你似乎没有使用你的 我
任何地方,所以我猜你不小心把它漏掉了?)。
for (var i = 0; i < resp.propertiesList.length; i++) {
var documentToSend = {
indexName: indexName,
type: type,
jsonContent: blabla
};
sendDocumentAjax(resp.propertiesList[i], documentToSend)
}
function sendDocumentAjax(listObj, documentData){
listObj.ajaxStatus = 'pending';
_TOOLS.Ajax({
type: 'POST',
url: urlTest,
data: documentData,
contentType: 'application/x-www-form-urlencoded',
dataType: 'json',
success: function (dataResponse) {
listObj.ajaxStatus = 'success';
},
error: function (xhr, ajaxOptions, errorThrown) {
var errorResponse = JSON.parse(xhr.responseText);
listObj.ajaxStatus = 'error: '+ errorResponse;
}
always: checkAjaxStatuses;
});
}
function checkAjaxStatuses(){
var pending = [];
var successes = [];
var errors = [];
for (var i = 0; i < resp.propertiesList.length; i++) {
if(resp.propertiesList[i].ajaxStatus === 'pending'){
pending.push(resp.propertiesList[i]);
}
if(resp.propertiesList[i].ajaxStatus === 'success'){
successes.push(resp.propertiesList[i]);
}
if(resp.propertiesList[i].ajaxStatus.indexOf('error') !== -1){
errors.push(resp.propertiesList[i]);
}
}
console.log('ajax completed.');
console.log(pending.length + ' pending.');
console.log(successes.length + ' succeeded.');
console.log(errors.length + ' failed.');
}
请注意我是如何使用单独的函数来发送 ajax 的,因此会为您发送 ajax 调用的每个对象创建一个新的闭包。您不能通过匿名函数完成所有这些操作,因为 i
始终是回调中的最大值(因为循环在任何 ajax 调用完成之前完成),使您无法引用原始函数您发送 Ajax 的对象。使用单独的函数可以避免这个问题。
关于javascript - 循环中的 Ajax 调用等到全部完成(错误或成功),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32777895/