最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - how do i wait for multiple ajax calls to complete from a .each loop - Stack Overflow

programmeradmin3浏览0评论

I am running a loop that updates records on a table but i need to wait for all of the records to update before i continue on.

How can I have jquery wait until all of the calls in the loopselectedrows function pletes? I have read about .deferred and .when but i am not sure how to implement either. they both do not seem to able to handle an array of calls if i where to change over to using an array for the ajax posts. Any help would be greatly appreciated.

this is the button that starts it all :

                click:  function () {

                        // validate all rows
                        var $selectedRows = $('#Table1').jtable('selectedRows');                                             
                        LoopSelectedRows($selectedRows, 'Validate');

/// wait here until all ajax calls have pleted // then continue with checking

                        // check for any row with an error 
                        var $ValidatedRows = $('#Table1').jtable('selectedRows');
                        var boolCheck = checkValidatedRows($ValidatedRows);                            


                        // if all records are succesfull then add them
                    // else alert user
                        if (boolCheck == true) {
                            LoopSelectedRows($selectedRows, 'Add');
                        }
                        else {
                            alert("Please correct invalid records and try again");
                        }

                }  

the first thing this does is take all of the records from the table and passes them to a looping function.

this is the looping function -

function LoopSelectedRows(SelectedRecords, actionType) {

    if (SelectedRecords.length > 0) {
        //Show selected rows
        SelectedRecords.each(function () {
            var record = $(this).data('record');

            record.PERSON_NAME = record.PERSON_ID;

            // Actions for loop 

            // Validation Action
            if (actionType == 'Validate') {
                 check = validateRecord(record);
            }

            // call add function   
            if (actionType == 'Add') {
                AddRecordToTable(record);
            }
        })
    };

}

this loop can either validate or add records for now i am only worried about the validation function

this is the validation function:

function validateRecord(dataRecord) {                

    $.ajax({
        url: "./ValidateAddRecord",
        type: 'POST',
        contentType: 'application/json',
        dataType: 'json',
        data: JSON.stringify(dataRecord),
        success: function (data) {
            if (data.Result == "OK") {

                // update record with message 
                $('#table1').jtable('updateRecord', { record: data.Record });

            }
            else {
                // display error
                alert(data.Message);
            }
        }
    });        
}

I am running a loop that updates records on a table but i need to wait for all of the records to update before i continue on.

How can I have jquery wait until all of the calls in the loopselectedrows function pletes? I have read about .deferred and .when but i am not sure how to implement either. they both do not seem to able to handle an array of calls if i where to change over to using an array for the ajax posts. Any help would be greatly appreciated.

this is the button that starts it all :

                click:  function () {

                        // validate all rows
                        var $selectedRows = $('#Table1').jtable('selectedRows');                                             
                        LoopSelectedRows($selectedRows, 'Validate');

/// wait here until all ajax calls have pleted // then continue with checking

                        // check for any row with an error 
                        var $ValidatedRows = $('#Table1').jtable('selectedRows');
                        var boolCheck = checkValidatedRows($ValidatedRows);                            


                        // if all records are succesfull then add them
                    // else alert user
                        if (boolCheck == true) {
                            LoopSelectedRows($selectedRows, 'Add');
                        }
                        else {
                            alert("Please correct invalid records and try again");
                        }

                }  

the first thing this does is take all of the records from the table and passes them to a looping function.

this is the looping function -

function LoopSelectedRows(SelectedRecords, actionType) {

    if (SelectedRecords.length > 0) {
        //Show selected rows
        SelectedRecords.each(function () {
            var record = $(this).data('record');

            record.PERSON_NAME = record.PERSON_ID;

            // Actions for loop 

            // Validation Action
            if (actionType == 'Validate') {
                 check = validateRecord(record);
            }

            // call add function   
            if (actionType == 'Add') {
                AddRecordToTable(record);
            }
        })
    };

}

this loop can either validate or add records for now i am only worried about the validation function

this is the validation function:

function validateRecord(dataRecord) {                

    $.ajax({
        url: "./ValidateAddRecord",
        type: 'POST',
        contentType: 'application/json',
        dataType: 'json',
        data: JSON.stringify(dataRecord),
        success: function (data) {
            if (data.Result == "OK") {

                // update record with message 
                $('#table1').jtable('updateRecord', { record: data.Record });

            }
            else {
                // display error
                alert(data.Message);
            }
        }
    });        
}
Share Improve this question edited Aug 21, 2014 at 20:13 Dan W asked Aug 20, 2014 at 15:25 Dan WDan W 891 silver badge6 bronze badges 2
  • 1 stackoverflow./questions/3709597/… – gloomy.penguin Commented Aug 20, 2014 at 15:28
  • 2 checkout jquery when/then and promise: api.jquery./category/deferred-object – Laurens Kling Commented Aug 20, 2014 at 15:29
Add a ment  | 

3 Answers 3

Reset to default 6

One fairly clean way to know when multiple ajax calls are done is to use promises and jQuery's $.when(). That will give you a callback when all the ajax calls are done. It will take a little bit of reorganization of your code to use that.

First, you return the $.ajax() promise from validateRecord():

function validateRecord(dataRecord) {                

    return $.ajax({
        url: "./ValidateAddRecord",
        type: 'POST',
        contentType: 'application/json',
        dataType: 'json',
        data: JSON.stringify(dataRecord),
        success: function (data) {
            if (data.Result == "OK") {

                // update record with message 
                $('#table1').jtable('updateRecord', { record: data.Record });

            }
            else {
                // display error
                alert(data.Message);
            }
        }
    });        
}

Then, you collect all the promises in LoopSelectedRows() and return a master promise using `$.when():

function LoopSelectedRows(SelectedRecords, actionType) {
    var promises = [];

    if (SelectedRecords.length > 0) {
        //Show selected rows
        SelectedRecords.each(function () {
            var record = $(this).data('record');

            record.PERSON_NAME = record.PERSON_ID;

            // Actions for loop 

            // Validation Action
            if (actionType == 'Validate') {
                 promises.push(validateRecord(record));
            }

            // call add function   
            if (actionType == 'Add') {
                promises.push(AddRecordToTable(record));
            }
        })
    };
    // return master promise
    return $.when.apply($, promises);
}

Then, you can use that final promise to know when everything is done.

click:  function () {
    // validate all rows
    var $selectedRows = $('#Table1').jtable('selectedRows');                                             
    LoopSelectedRows($selectedRows, 'Validate').then(function() {
         // all the ajax calls in LoopSelectRows are done now

         // check for any row with an error 
         var $ValidatedRows = $('#Table1').jtable('selectedRows');
         var boolCheck = checkValidatedRows($ValidatedRows);                            

         // if all records are succesfull then add them
         // else alert user
         if (boolCheck == true) {
             LoopSelectedRows($selectedRows, 'Add');
         } else {
             alert("Please correct invalid records and try again");
         }
    });

FYI, you probably also want to change AddRecordToTable() to return a promise so it can work the same way (though it is not required because you aren't trying to wait for that operation to be done).

$.active returns the number of active Ajax requests. Use $.active==0 means no ajax requests are active. You could also use ajaxStart and ajaxStop to keep track of when requests are active.

Thank you jfriend00, your solution seems to have solved my issues.

Below is the updated version i am now using for anyone interested :

click:  function () {

                    // validate all rows

                    var $selectedRows = $('#table1).jtable('selectedRows');

                        LoopSelectedRows($selectedRows, 'Validate').then(function () {


                            // check for any row with an error 
                            var $ValidatedRows = $('#table1).jtable('selectedRows');
                            var boolCheck = checkValidatedRows($ValidatedRows);

                            // if all records are succesfull then add them
                            // else alert user
                            if (boolCheck == true) {
                                LoopSelectedRows($selectedRows, 'Add');
                            }
                            else {
                                alert("Please correct invalid records and try again");
                            }
                        });
                }




// loop function
function LoopSelectedRows(SelectedRecords, actionType) {
    var promises = [];
    if (SelectedRecords.length > 0) {
        //Show selected rows
        SelectedRecords.each(function () {
            var record = $(this).data('record');

            // Actions for loop 

            // Validation Action

            if (actionType == 'Validate') {
                 promises.push(validaterecord(record));
            }


            // call add function   
            if (actionType == 'Add') {
                AddRecordToTable(record);
            }
        })
    };        
    return $.when.apply($, promises);
}


  // validate function
function validaterecord(dataRecord) {
    var def = $.Deferred();
    $.ajax({
        url: "./ValidateAddRecord",
        type: 'POST',
        contentType: 'application/json',
        dataType: 'json',
        data: JSON.stringify(dataRecord),
        success: function (data) {
            if (data.Result == "OK") {

                // update record with message 
                $('#table1).jtable('updateRecord', { record: data.Record });

                // resolve token
                def.resolve();

            }
            else {
                // display error
                alert(data.Message);
            }
        }
    });

    return def.promise();
}
发布评论

评论列表(0)

  1. 暂无评论