Suppose I have a event handler which makes two AJAX calls to the server:
$("#foo").click(function(){
$.get("bar", function(){ alert("Hello"); });
$.get("baz", function(){ alert("World"); });
});
I realize that the order in which the callbacks are invoked is nondeterministic, since it depends on how long each request takes, etc.
But here's my question: is it guaranteed that I'll reach the end of my event handler before either of the callback functions are invoked? I've read that all Javascript for a page executes in a single thread, so I think that implies that my click
event handler is guaranteed to complete before any of the callbacks can be invoked.
Is this correct? Or is it possible that the first request might be complete AND the first callback executed before we even get to the end of our event handler?
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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With