Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are event handlers guaranteed to complete before AJAX callbacks are invoked?

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?

like image 445
Eli Courtwright Avatar asked Apr 03 '12 18:04

Eli Courtwright


3 Answers

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.

See also

  • JavaScript equivalent of SwingUtilities.invokeLater()
  • "atomic" operation desturbed by asynchronous ajax callbacks
  • Are there any atomic javascript operations to deal with Ajax's asynchronous nature?
  • how is async programming (promises) implemented in javascript? isn't javascript a ui-threaded environment?
like image 88
Tomasz Nurkiewicz Avatar answered Oct 18 '22 17:10

Tomasz Nurkiewicz


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

like image 4
Juan Mendes Avatar answered Oct 18 '22 16:10

Juan Mendes


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

like image 1
Ustaman Sangat Avatar answered Oct 18 '22 15:10

Ustaman Sangat