4

Hi i am creating a batch update for my local store using for loop and async ajax call.

My problem is that my loop continues even though my ajax call still not yet successfully finished.

How can we manage to make for loop wait unit the response of the ajax response before continuing the loop?

Any help is appreciated. Thanks!!!

Below is my sample code:

var counter =0;
var totalRow = 3000;
for (var i = 0, l = totalRow; counter <= l; i++) {

    var defectssurl = 'https://test.com/mywcf.svc/GetListAllPaging?id=' + counter;

    Ext.Ajax.request({
        url: defectssurl,
        method: "POST",
        params: '',
        success: function (resp) {

            console.log("load first 500 records");
            var data = Ext.JSON.decode(resp.responseText); //encode Json List

            if (counter == 0) {
                defectsLocalStore.getProxy().clear();
                // Also remove all existing records from store before adding
                defectsLocalStore.removeAll();
            }

            Ext.Array.each(data, function (record) {
                counter = counter + 1;
                defectsLocalStore.add(record);
            });

            defectsLocalStore.sync(); // The magic! This command persists the records in the store to the browsers localStorage

            //records is now same as the total records
            if (counter >= totalRow) {
                pCallback();
            }

            //continue loop
        },
        headers: {
            'Content-Type': 'application/json; charset=utf-8'
        },
        failure: function (resp) {

        }
    });

}
Barmar
  • 741,623
  • 53
  • 500
  • 612
BizApps
  • 6,048
  • 9
  • 40
  • 62
  • A loop can't wait for anything asynchronous, because Javascript is single-threaded. The async update doesn't happen until the loop finishes and you return to the main event loop. – Barmar Apr 10 '14 at 04:54
  • Instead of doing them in a loop, have the `success` function of row `i` send the AJAX request for row `i+1`. – Barmar Apr 10 '14 at 04:58
  • You can try to use promises. Instead of executing the AJAX call, return an array of promises. You can then use `then` to execute when all promises in the array are complete – jasonscript Apr 10 '14 at 04:59
  • If you want do run your ajax calls once at a time, you simply can't use a `for` loop. Instead, you have to start the next ajax call in the success handler of the previous one. See http://stackoverflow.com/questions/22952965/how-to-break-out-of-the-for-loop-in-nodejs/22953032#22953032 for an example of doing this posted earlier today. – jfriend00 Apr 10 '14 at 05:38

1 Answers1

10

Please don't use "for loop". Instead in the success callback increase the counter and re-trigger itself. something like below.

function mySyncFunction (counter, totRecords){
   if(counter === undefined) 
     counter = 0;   
   if(counter >=totRecords) return;

   var defectssurl = 'https://test.com/mywcf.svc/GetListAllPaging?id=' + counter;
   Ext.Ajax.request({
     url:defectssurl,
        // snip // your code here
     success: function (resp) {
        // snip // your code here
        counter++;
        mySyncFunction(counter, totRecords);
     }
     // snip // your code here
});
Abhi
  • 824
  • 9
  • 8
  • 3
    Please don't ever recommend `async: false`. I have never, ever seen that be the best way to implement any Ajax call or, even worse, a series of Ajax calls. It locks up the browser and prevents user input during the ajax call. – jfriend00 Apr 10 '14 at 05:40
  • Async falls really not recommended but thanks Abhi, your logic works on mine :D – BizApps Apr 10 '14 at 06:03
  • Agreed. I will take out that option. – Abhi Apr 10 '14 at 06:07