2

I call ajax jquery function inside .each loop, and I want to do an action just when all the ajax calls inside the loop finish and success.

$(".checked-box").each(function () {
     // ajax call goes here
});
$('.messsage').html('all requests done');

How to do that? without async: false because this blocks the browser.

Amr Elgarhy
  • 66,568
  • 69
  • 184
  • 301

4 Answers4

8

Deferreds can make your work simpler.

var deferreds = $('.checked-box').map(function(i, elem) {
  return $.ajax(params);
});

$.when.apply(null, deferreds.get()).then(function() { ... });

Hope this should work.

The concept is

$.when(
    $.ajax( "1" ),
    $.ajax( "2" ),
    $.ajax( "3" )
).then( successFunc, failureFunc );
Boopathi Rajaa
  • 4,659
  • 2
  • 31
  • 53
  • seams good, while I am not familiar yet with Deferreds, for example if I put my .each loop inside this .when it will work? and will get the ajax success response? – Amr Elgarhy Jul 06 '11 at 05:23
  • the success function in ajax is something like deferred only. it is called once that particular request has responded. you can do whatever you want to do there in success .. i.e. after each ajax response. I havent tested the code with each. Mostly the above code should work. I ll test it and post the edit later. – Boopathi Rajaa Jul 06 '11 at 05:29
  • I tested it with .each, it didn't wait till all the loop done, the then ran before :( – Amr Elgarhy Jul 06 '11 at 05:39
3

This is one way:

var numberOfPendingRequests = 8;
$(".checked-box").each(function () {   
   $.ajax({
     success: function(){
        ...
        numberOfPendingRequests --;
        if(numberOfPendingRequests == 0) allDone();
     }
   });
});
function allDone(){
  $('.messsage').html('all requests done');
}

You can calculate the initial numberOfPendingRequests based on your number of checkboxes or start it at 0 an increment it before each ajax request, but this is the general idea.

Hope this helps. Cheers

Edgar Villegas Alvarado
  • 18,204
  • 2
  • 42
  • 61
1

Try this:

AjaxRequestCount = 0;
//JUST prepare ajax requests here, do not send yet...
$(".checked-box").each(function () {
     AjaxRequestCount += 1; //Count number of ajax request
     //set "success:" of each ajax to Success() function
});

//Send ajax requests here, use a loop...

for(i=0;i<AjaxRequestCount;i++)
{
   //ajax[i].send
} 

//Fires for each ajax success...
function Success()
{
    SuccessAjaxRequestCount += 1;
    Check(); //Check right after each ajax success
}

//Checks if already reached the expected number of ajax success...
function Check()
{
    if(SuccessAjaxRequestCount  == AjaxRequestCount )
    {
        alert("done!");
    }
}
kazinix
  • 28,987
  • 33
  • 107
  • 157
  • It worked for me, and It showed the alert once at the end of the loop and all ajax calls. – Amr Elgarhy Jul 06 '11 at 05:13
  • Yeah, I made an error, now I add a loop that will send ajax request after ajax preparation so that it `success:` of each ajax wont fire until all ajax are prepared to be sent. – kazinix Jul 06 '11 at 05:15
  • @amr , he modified code after my comment , anyway thats kool it works – kobe Jul 06 '11 at 05:16
  • @Amr - You might encounter a problem like kobe, how if the ajax receives a successful response prior to sending of the ajax next to it? `SuccessAjaxRequestCount == AjaxRequestCount` will be true, alert will pop-up! Please see revisions. Thanks! – kazinix Jul 06 '11 at 05:31
0

look at section 3.1 of this post for a complete example of waiting for asynchronous stuff to end

Thiago Duarte
  • 941
  • 9
  • 21