1

basically I want a Jquery function to call a PHP script multiple times, and every single time, load the response into a div, this is the code I have now:

images = 10;
while(images > 0)
    {
        $.ajax({        
            type: "POST",
            url: "processimage.php",
            data: { image : 1 },
            async: false,
            success: function(data) {   
                $( "#logger" ).append(data+ '<br />');
            }
        });
        images--;
    }

What this code is doing is processing all the images and then appending the full response, but I want it to append the response for every single image. Somehow the while block is entirely being processed before updating the #logger div. Am I missing something?

3
  • 2
    until you remove async: false, this is impossible with your while loop. The browser will be locked up until the while loop is complete. Commented Nov 1, 2013 at 18:48
  • The while block actually runs before you get the response. ajax calls are async operations. jQuery will call your callback as soon as a response is available. Commented Nov 1, 2013 at 18:50
  • Try wrapping the code inside the while loop in setTimeout with a delay of 0 ms, it may render each image one at a time. setTimeout causes the DOM the render before executing the next flow. See here for more detailed info: stackoverflow.com/questions/779379/… Commented Nov 1, 2013 at 18:53

1 Answer 1

2

you must remove the async: false. which in turn allows the requests to complete and be appended as they finish. However, you'll then realize that they are being appended out of order! to fix that, we can use promise objects and .then.

images = 10;

var req = $.ajax({
    type: "POST",
    url: "processimage.php",
    data: {
        image: images
    },
    success: function (data) {
        $("#logger").append(data + '<br />');
    }
});
images--;

while (images > 0) {
    req.then(function(){
        return $.ajax({
            type: "POST",
            url: "processimage.php",
            data: {
                image: 1
            },
            success: function (data) {
                $("#logger").append(data + '<br />');
            }
        });
    });
    images--;
}

Now, there's still one more possible issue. if you needed to pass the current value of images with each request, the previous code will send all requests after the first with the last value of images. To fix that, we can use an iffe.

images = 10;

var req = $.ajax({
    type: "POST",
    url: "processimage.php",
    data: {
        image: 1
    },
    success: function (data) {
        $("#logger").append(data + '<br />');
    }
});
images--;

while (images > 0) {
    (function(i){
        req.then(function(){
            return $.ajax({
                type: "POST",
                url: "processimage.php",
                data: {
                    image: i
                },
                success: function (data) {
                    $("#logger").append(data + '<br />');
                }
            });
        });
    })(images);
    images--;
}

And then you can make it DRYer as suggested below by storing the options in a separate variable:

images = 10;

var ajaxOpts = {
    type: "POST",
    url: "processimage.php",
    data: {
        image: 1
    },
    success: function (data) {
        $("#logger").append(data + '<br />');
    }
};

var req = $.ajax(ajaxOpts);
images--;

while (images > 0) {
    (function(i){
        req.then(function(){
            ajaxOpts.data.image = i;
            return $.ajax(ajaxOpts);
        });
    })(images);
    images--;
}
Sign up to request clarification or add additional context in comments.

1 Comment

You could make that code DRYer by saving all the $.ajax() options as a variable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.