0

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!

7
  • 2
    I would recommend using Promises. The following link is a good introduction: scotch.io/tutorials/javascript-promises-for-dummies (And it's not just for dummies!) In particular, check out the Chaining Promises section. Commented Apr 12, 2017 at 0:07
  • 1
    So which way are you trying to do. Do something after ALL ajax have finished, or, one ajax starts after another has finished? Commented Apr 12, 2017 at 0:08
  • one approach is to send all the data at once and have server side script update progress in session variable....then set up another long polling ajax call to monitor progress from that session variable Commented Apr 12, 2017 at 0:22
  • @A.Lau I'm trying to do one AJAX call after another, waiting for the previous one to finish before calling the next. And setting jQuery to synchronous mode just freezes the browser. Commented Apr 12, 2017 at 0:23
  • Thanks, I will look into promises and the polling solution. Commented Apr 12, 2017 at 0:23

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

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.