Reputation: 1849
I have a button tied to a click handler -- which makes one or more AJAX calls, depending on how many items are in an array. I use the blockUI jquery plugin to show a message while the ajax call(s) are being made, then I show the results, and remove the blockUI message by calling $.unblockUI();.
Problem: For some reason, no matter how many times I want the ajaxCall function to execute, after the FIRST ajax call completes, the messaging is removed even though the loop still continues to execute, and the results display correctly in the #results div. I want the full number of loop iterations to complete before removing the messaging, but it seems like its not executing sequentially. Here is the code in question:
$("#myButton").live("click", function(){
$.blockUI({ message: '<img src="new_loader.gif" /><h2>Getting Config Files</h2><small>Please be patient.</small>',
css: {
border: 'none',
padding: '15px',
backgroundColor: '#FFF',
'-webkit-border-radius': '10px',
'-moz-border-radius': '10px',
color: '#000'
}
});
for (var i=0; i< myArray.length; i++)
{
ajaxCall(myArray[i]);
}
$("#results").show('slow');
$.unblockUI();
return false;
});
Is there an explanation for why the code AFTER the loop is executing even though the loop isn't complete yet? Any help it appreciated! Thanks.
Upvotes: 4
Views: 2299
Reputation: 236172
Whatever ajaxCall()
does, if it creates an XMLHttpRequest
asyncronously, this is the correct behavior. An Ajax request is default non-blocking, I guess that is the reason why your code after your loop is executed immediately.
One possible way I can think of to solve this is, to create a counter variable, which increases on each call from ajaxCall()
and decreases in each complete
handler (XHR readystate 4). When that counter comes to zero, you should execute your code after the loop.
function increase() { // goes into your `ajaxCall()` or `beforeSend` callback
mynamespace.requests++;
}
function decrease() { // goes into your `complete` callbacks
if(--mynamespace.requests) {
$("#results").show('slow');
$.unblockUI();
}
}
Upvotes: 2
Reputation: 21864
ajaxCall(myArray[i]);
is done asynchronous so the method is fired within the loop, but the execution will take a little more time, thus ending after the rest of the code is finished.
an nice way of dealing with this kind of behaviour is found in this article: Asynchronous method queue chaining in JavaScript
Upvotes: 4
Reputation: 28893
I'm guessing that ajaxCall
is async? This will cause the code to not block on the loop, essentially completing the loop quickly and then progressing on.
What you can do is provide a callback function with a counter to check if all the ajax calls are complete.
var count = arr.length - 1;
for(var i = 0; i < arr.length; i++)
{
ajaxCall(arr[i], function () {
if(--count == 0)
{
/* All AJAX calls complete, continue execution */
}
});
}
Upvotes: 1