tags:

views:

38

answers:

2

I would like to do a series of get requests, and then preform some action after all of the get requests have finished. Below is a starting point on the code I have, but since the get request is asynchronous, the "do some action after all getJSON requests finish" executes right away.

What is the proper/best way of going about this?

...
$.each(array, function(i, element) {
    // setup url and params
    $.getJSON(url, params, function(data) {
        // do work on data
    }
}
// do some action after all getJSON requests finish
...

I considered having a counter for the number of elements in the array, decrementing it, and performing the action when it reaches zero, but I am worried that the operation is not atomic and may encounter errors. Below is an example of what I was thinking of, but I am uncertain if it would always work correctly.

...
$.each(array, function(i, element) {
    var items_remaining = array.length;
    // setup url and params
    $.getJSON(url, params, function(data) {
        // do work on data
        items_remaining = items_remaining - 1;
        if ( items_remaining === 0 ) {
            // do some action after all getJSON requests finish
        }
    }
}
....
+1  A: 

Don't worry about atomicity. Javascript is single threaded in execution and concurrent access to "shared" data simply doesn't happen. Your callback will never be called concurrently. Your example looks fine.

spender
+1  A: 

If you've got control over the server-side processing script, how about modifying it to accept an array of items so they can be batch processed, rather than firing off one item at a time and incurring all the overhead of putting up/tearing down an HTTP call for each? With just that single call, you can have the callback handler fire off the "do something after..." logic and not have to worry if you've reached end of the .each() loop yet.

Making it a synchronous call would also guarantee that the post-processing logic won't get executed until the ajax call is done. But if the processing takes a "long" while, this will lock up the browser for the duration. Simply placing the post-processor into a function and having that function called from the ajax handler gets around that, though.

Beyond that, your option with a counter is the only other practical option.

Marc B