Ajax Call In For Loop Wait Until All Done (error Or Success)
Solution 1:
The way I find easiest to handle these things is keeping track of the status of each of the Async calls in an object or array. Each time a call completes, flag it as done and check if there are any more running. You could even just add a boolean to your object to check if asyncIsBusy
, or a property for ajaxStatus
.
I am assuming here that indexName
and type
are coming from resp.propertiesList
(you don't seem to use your i
anywhere, so I guess you left that out by accident?).
for (var i = 0; i < resp.propertiesList.length; i++) {
var documentToSend = {
indexName: indexName,
type: type,
jsonContent: blabla
};
sendDocumentAjax(resp.propertiesList[i], documentToSend)
}
functionsendDocumentAjax(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;
});
}
functioncheckAjaxStatuses(){
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.');
}
Note how I used a separate function to send the ajax, so a new closure is created for each object that you sent an ajax call for. You can't do all of this through anonymous functions because i
would always be the maximum value in the callbacks (since the loop finishes before any ajax call is completed), leaving you no way to reference the original object you sent the Ajax for. Using a separate function circumvents this issue.
Solution 2:
Q.allSettled
can help you on this, you may find the npm package here - https://www.npmjs.com/package/q.
Solution 3:
try setting async: false in ajax call
var promise = _TOOLS.Ajax({
type: 'POST',
url: urlTest,
data: documentToSend,
async: false,
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.");
}
});
Solution 4:
Go for a recursive approach:
ajaxLoopArray(myArray, function(){ /* do something when finish */ });
functionajaxLoopArray(someArray, callbackFunction){
if(someArray.length>0){ //condition to break the loop
data = someArrapy.pop(); // pop removes the last element from an array and returns that element.
$.ajax({
data
}).done(function(x){
//success
})
.fail(function(){
//catch the error here
})
.always(function(){
ajaxLoopArray(someArray, callbackFunction); //recursive call: keep on looping independently of success or error
});
}else{
callbackFunction(); //when everything was done
}
}
Post a Comment for "Ajax Call In For Loop Wait Until All Done (error Or Success)"