简体   繁体   中英

execute code after AJAX loop finished

I have an AJAX call that gets called "i" amount of times. I want to execute the rest of the code only after the last AJAX processData callback function was finished (It fills values of the .csv into an array called "lines" and I need the finished array after all iterations have finished). So far it only works by using "setTimeout()" which is not a nice solution

for (var i = 0; i < options.length; i++) {
    (function(index) {
        $.ajax({
            type: "GET",
            url: options[index] + ".csv",
            dataType: "text",
            success: function(data) {
                processData(data, options[index], type)
            }
        });
    })(i);
}
setTimeout(function() {
    getAveragePercentages(lines);
}, 500)

You can use the JavaScript promise functionality.

Make AJAX request in the promise. Create an array which will contains all these promise.

Promise.all will be executed after all promise get resolved.

 var promiseArr = []; for (var i = 0; i < options.length; i++) { var promise = new Promise(function(resolve, reject) { (function(index) { $.ajax({ type: "GET", url: options[index] + ".csv", dataType: "text", success: function(data) { processData(data, options[index], type); resolve('outputIfany') } }); })(i); }); promiseArr.push(promise); } Promise.all(promiseArr).then(function(values) { getAveragePercentages(lines); }); 

set up a counter and check it's value before calling your function

$("#counter").html("0");
for(var i=0;i<options.length;i++){
            (function(index){       
                $.ajax({ 
                    type: "GET",
                    url: options[index]+".csv",
                    dataType: "text",
                    success: function(data) {
                    processData(data, options[index], type)
                    var counter = $("#counter").html();
                    if( counter == options.length ){
                      getAveragePercentages(lines);
                    }
                     $("#counter").html(counter+1);
                   }
                });

            })(i);
        }
for (var i = 0; i < options.length; i++) {
    (function (index) {
        $.ajax({
            type: "GET",
            url: options[index] + ".csv",
            dataType: "text",
            success: function (data) {
                processData(data, options[index], type)
            }
        });
        counter = counter + 1;
    })(i);
    if (i == options.length) {
        getAveragePercentages(lines);
    }
}

You can do something like this.

after last Loop Success call function

var totalRec = options.length;
for(var i=0;i<options.length;i++){
    (function(index){       
        $.ajax({ 
            type: "GET",
            url: options[index]+".csv",
            dataType: "text",
            success: function(data) {processData(data, options[index], type)


           if(i == (totalRec-1)){
              getAveragePercentages(lines);
           }
        }
        });
    })(i);
}

or

var totalRec = options.length;
    for(var i=0;i<options.length;i++){
        (function(index){       
            $.ajax({ 
                type: "GET",
                url: options[index]+".csv",
                dataType: "text",
                success: function(data) {processData(data, options[index], type)


            }
            });
        })(i);

     if(i == (totalRec-1)){
          getAveragePercentages(lines); // gets called only when condition is true
      }
    }

It is not a good practice to use a setTimeOut for wait the ajax call, in my experience I've been using recursive functions for doing this, in your case you can do the following:

var counter = 0;
function main()
{
    counter = 0;
    doAjaxCall(counter);
}

function doAjaxCall(counter)
{
    (function(index){       
                $.ajax({ 
                    type: "GET",
                    url: options[index]+".csv",
                    dataType: "text",
                    success: function(data) {
                       processData(data, options[index], type);
                       if(counter < options.length)
                       {
                           counter++;
                           doAjaxCall(counter); //We call the same function but with the next index
                       }
                       else
                       {
                          //The loop finished, countinue code after your for loop
                       }
                    }
                });
            })(i);
}

I added a function as a parameter. The AJAX calls the function when the load is completed.

function loadDoc(call_back_func) {
  const xhttp = new XMLHttpRequest();
  xhttp.onload = function() {
    json_data = JSON.parse(this.responseText);
    call_back_func();
  }
  xhttp.open("GET", "kanban_personal_template.json");
  xhttp.send();
}

function load_call_back()
{
    console.log(json_data);
}
loadDoc(load_call_back);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM