Nick
Nick

Reputation: 417

Using AJAX to do a set of sequential tasks on PHP server

I'm having an issue with the inherent asynchronous-ness of AJAX with what I'm trying to accomplish...

Using a file upload form, I'm trying to send a set of data to my LAMP server which then loops through each subset of the data and generates a PDF for each subset. This takes a good 2 minutes or so to process all of the PDFs since there are so many (like 100) being generated for each subset of data.

I am hoping to use JavaScript/jQuery to segment the data into subsets that I will post to the server one at a time, and as each PDF is generated, get a response from the server and increment a progress bar, then send the next request.

How would you accomplish this in a loop? What's below doesn't work because jQuery doesn't care about the state of the server and sends all requests asynchronously.

var i = 0;
$.each(data_stuff, function(key, value) {
    $.post( window.location.href, { 
        stuff: key,
        data: value
    }).done(function( data ) {
        if (data == 1) {
            $('div#counter').text(i);
        }
    });                         
    $i++;
});

Thanks!

Upvotes: 0

Views: 79

Answers (1)

Bart Langelaan
Bart Langelaan

Reputation: 529

Assuming data_stuff is an Object, you can try this:

var i = 0;

// We need an array (not object) to loop trough all the posts. 
// This saves all keys that are in the object:
var keys = Object.keys(data_stuff);

function postNext() {

    // For every POST request, we want to get the key and the value:
    var key = keys[i];
    var value = data_stuff[key];

    $.post( window.location.href, { 
        stuff: key,
        data: value
    }).done(function( data ) {
        if (data == 1) {
            $('div#counter').text(i);
        }

        // Increment i for the next post
        i++;

        // If it's the last post, run postsDone
        if(i == keys.length) {
            postsDone();
        }
        // Else, run the function again:
        else {
            postNext();
        }
    });
});

postNext();

function postsDone() {
    // All data was posted
}

This will only post the next bit of data_stuff after the previous $.post was done.

Upvotes: 2

Related Questions