open source guy
open source guy

Reputation: 2787

How to stop the loop until the response get in jquery?

I have code like this. Loop length is grater than 100.

$('.check_box_ping:checked').each(function(i, obj) {
    $.post(
        "mass_ping.php",
        "ping", 
        function(response) {
        }
    );
});

Now 100 $.post() calls occur simultaneously. I want to execute each $.post() sequentially after getting the response of the previous $.post() from the server.

Upvotes: 0

Views: 4085

Answers (3)

Nanne
Nanne

Reputation: 64399

You can do 2 things

  1. Change your code so you call the next post from the return function of your first post. This will need some change in your current loop, but would keep everything running smoothly
  2. quicker, but dirty, is to make the post synchronous. You can find out how in this question: how to make a jquery "$.post" request synchronous . I would advice against this, as it would cripple your page during the load(s).

Upvotes: 1

Fabrizio Calderan
Fabrizio Calderan

Reputation: 123377

With a deferred object you could chain all your ajax calls returning a promise inside some chained pipe() methods (see the console output below)

Markup and js

<body>
    <input type="checkbox" checked />
    <input type="checkbox" checked />
    <input type="checkbox" checked />
    <input type="checkbox" checked />  
</body>

<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script>
function doRequest() {
    return $.post("script.php").done(function(response) {
       console.log('Loaded in %d seconds', response);
    });
}

$(document).ready(function(){

    var dfd   = $.Deferred(),
        chain = dfd;

    $('input:checked').each(function() {
        chain = chain.pipe(function() {
            return doRequest().promise();
        });
    });

    chain.done(function() { 
       console.log('done')
    });

    return dfd.resolve();
});
</script>

script.php

<?php
   $seconds = rand(2, 5); 
   sleep($seconds);
   header("Content-type: text/html");
   echo($seconds);
?>

Sleep() was used only to emulate a random latency on the response. On the javascript console you should see something like this:

output

Upvotes: 6

jfriend00
jfriend00

Reputation: 707198

The only way to pause your loop for each one is to make the post synchronous which is generally a very bad user experience (it hangs the browser).

What I would suggest instead is that you restructure your loop so you do the next iteration from the completion of the previous post:

(function() {

    var checked = $('.check_box_ping:checked');
    var index = 0;

    function next() {
        if (index < checked.length ) {
            var item = checked.eq(index++);
            // use item here for your post
            $.post({...}, function(response) {
                // do your normal handling of the response here
                ...
                // now kick off the next iteration of the loop
                next();
            });
        }
    }
    next();

})();

Upvotes: 2

Related Questions