Suppose I have a event handler which makes two AJAX calls to the server:
$(\"#foo\").click(function(){
$.get(\"bar\", function(){ alert(\"Hello\"); });
Yes, JavaScript is single threaded, so your execution will never get preempted.
Asynchronous callbacks and events work the same way; your handler for mousedown
is guaranteed to finish before your handler for a mouseup
, even if your mousedown
handler takes 2 seconds and you let the mouse go immediately.
The same goes for an AJAX callback, it gets put into the same (kind of) queue as events waiting to be processed
Yes, this is guaranteed and you are right - there is just a single thread (ignoring web-workers for the moment). When a piece of JavaScript code executes (occupies the execution thread) and an AJAX callback arrives (or any other GUI event, timeout, etc.) it is queued and waits until the execution thread is free (current piece of code finishes).
JavaScript engine will never interrupt running code to handle incoming event - events will always gently wait in a queue. This is the reason why the GUI appears to be freezing when CPU-intensive code is executing - no events are handled. Also this is why synchronous AJAX requests are bad.
I realize that the order in which the callbacks are invoked is nondeterministic, since it depends on how long each request takes, etc.
In the way you have written it yes.. but there are ways to organize and control this.. namely deffereds and promises.
Here is a good overview: http://net.tutsplus.com/tutorials/javascript-ajax/wrangle-async-tasks-with-jquery-promises/
Proper use of them will ensure that you won't run into whatever problem you seem to be trying to avoid.
** As @Juan has pointed out, this isn't the black and white answer for the question you asked. I'm just trying to point you in different directions or ways to look at the same problem so you can define your expected behavior more explicitly.
An interesting twist to this would be instead of $.get(), lets say we were using promises that we get from somewhere else (i.e. the actual async call was made elsewhere) (-Why would we have such a situation? Well maybe we have a memoized query function.)
Now if one were using jQuery promises, the callbacks would be invoked synchronously if already resolved. Is that ever an issue? Well depends on your requirement. If it does then you could wrap the callback code in a setTimeout(cb, 0).
On the other hand, what if you wanted the callbacks to be preempted? See my examples here