Skip to content Skip to sidebar Skip to footer

Ajax Call In For Loop Wait Until All Done (error Or Success)

I am making AJAX calls in a for loop and I would like to wait until all of them are done before doing something. I am trying to use promises but there is something that I'm missing

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 typeare coming from resp.propertiesList(you don't seem to use your ianywhere, 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)"