4

I'm a little bit confused about how browsers handle JavaScript events.

Let's say I have two event handlers attached to buttons A and B. Both event handlers take exactly the same time to complete. If I click on button A first and button B next, is it true that the event handler for the button A is always executed first (because the event loop is a FIFO queue), but when they finish is completely unpredictable? If so, what actually determines this order?

9
  • 1
    They're executed sequentially on a single thread. A will finish before B ever starts. You can try this by sleep()ing in one handler, and verifying that the second handler will not start until it has finished. Commented Sep 16, 2013 at 6:29
  • I don't observer this behaviour. See this fiddle. When I click button 1, then button 2, the event handler for button 2 does not block. Commented Sep 16, 2013 at 6:38
  • 2
    @CookieMonster Because you're not actually sleeping, you're using setTimeout, which essentially registers a function with the engine to be called back at a later time. setTimeout returns immediately. If you try the code I linked to, you'll see the browser hang. Commented Sep 16, 2013 at 6:40
  • 1
    That's cos you used a setTimeout Commented Sep 16, 2013 at 6:40
  • Try this: jsfiddle.net/Urjh2 You'll see that the "start" outputs never show up, because the function is already spinning. Commented Sep 16, 2013 at 6:43

3 Answers 3

5

Yes. The order of event handlers executed is guaranteed, and in practice they will not overlap.

This is the beauty of the event loop as a concurrency model. You don't have to think about threading issues like deadlocks, livelocks and race conditions most of the time (though not always).

Order of execution is simple and JavaScript in the browser is single threaded most of the time and in practice you do not have to worry about order of execution of things.

However the fact order of mouse events is guaranteed has hardly anything has to do with JavaScript. This is not a part of the JavaScript language but a part of something called the DOM API, the DOM (document object model) is how JavaScript interacts with your browser and the HTML you write.

Things called Host Objects are defined in the JavaScript specification as external objects JS in the browser works with, and their behavior in this case is specified in the DOM API.

Whether or not the order DOM events are registered is guaranteed is not a part of JavaScript but a part of that API. More specifically, it is defined right here. So to your question: Yes, order of event execution is certain except for control keys (like (control alt delete)) which can mess order of evaluation up.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for a great answer. I have a much better understanding of how JavaScript works now. Maybe you could also add to your answer that not only they are executed first, but the subsequent event is blocked until the first one finishes as @JonathonReinhart clarified for me.
@CookieMonster I'm not sure that this is guaranteed by the DOM API itself, it is in fact the case. I will investigate the spec further and return with results with citations rather than educated guesses :) Meanwhile, you can certainly count on the fact that in practice just like Jonathon said it is the case when you use events normally.
2

The Javascript engine is single threaded. All of your event handlers happen sequentially; the click handler for A will be called, and finish before the handler for B ever starts. You can see this by sleep()ing in one handler, and verifying that the second handler will not start until the first has finished.

Note that setTimeout is not valid for this test, because it essentially registers a function with the engine to be called back at a later time. setTimeout returns immediately.

This fiddle should demonstrate this behavior.

4 Comments

Nice explanation. Can you say , why the $("#output").text("button1 start"); will not executed before the pausecomp(5000); executes ?
I'm not really sure. I've never actually used jQuery before, so I'm not sure what it's doing under the hood. I would speculate that there's some sort of buffering going on, and the spinning function is preventing the update thru the DOM from happening.
@JonathonReinhart "The JavaScript engine is single threaded" is wrong in several ways. It's kinda safe to assume that it is mostly single threaded most of the time. However that has little to do with why OP is getting the behavior he observed. It is not specified in the engine, or the language, but in the DOM API.
@BenjaminGruenbaum I look forward to hearing the low-level details, as my answer was done in a pretty hand-waving fashion anyway.
-1

Well the commands are indeed in a FIFO when executed by javascript. However, the handlers may take different amounts of time to send you the result. In this case the response from handler B may come back earlier and response from handler A may come later.

3 Comments

This is counter to what others have said so far. Please see the comments. Are you sure this is correct?
Maybe he is talking about XHR handlers which make requests in the order they are called but the response can come in any order, and callbacks attached to those requests will run in order of the responses irrespective of the calling order.
This answer is incorrect in any browser that implements the DOM API according to the specification.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.