3

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?

CookieMonster
  • 1,829
  • 2
  • 22
  • 46
  • 1
    They're executed sequentially on a single thread. A will finish before B ever starts. You can try this by [`sleep()`ing](http://stackoverflow.com/questions/951021/what-do-i-do-if-i-want-a-javascript-version-of-sleep) in one handler, and verifying that the second handler will not start until it has finished. – Jonathon Reinhart Sep 16 '13 at 06:29
  • I don't observer this behaviour. See [this fiddle](http://jsfiddle.net/qttcP/). When I click button 1, then button 2, the event handler for button 2 does not block. – CookieMonster Sep 16 '13 at 06: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. – Jonathon Reinhart Sep 16 '13 at 06:40
  • 1
    That's cos you used a setTimeout – Neeraj Sep 16 '13 at 06:40
  • Try this: http://jsfiddle.net/Urjh2/ You'll see that the "start" outputs never show up, because the function is already spinning. – Jonathon Reinhart Sep 16 '13 at 06:43
  • @JonathonReinhart Thank you for the fiddle. I was trying to make sure event handlers were executed in a predicted order in my web app. So as long as one event handler is triggered first and being processed, others automatically block. Thanks a lot. – CookieMonster Sep 16 '13 at 06:46
  • @CookieMonster 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. – Benjamin Gruenbaum Sep 16 '13 at 06:52
  • @BenjaminGruenbaum yes, I also found it very easy to program. Btw, what if I press Button A first, and presses Button B a 0.001 seconds later? Is it still guaranteed that the event handler for Button A is executed first? – CookieMonster Sep 16 '13 at 06:54
  • @CookieMonster Note - 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. 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](http://www.w3.org/TR/DOM-Level-3-Events/#event-order-and-loops). 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. – Benjamin Gruenbaum Sep 16 '13 at 06:59

3 Answers3

4

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.

Community
  • 1
  • 1
Benjamin Gruenbaum
  • 246,787
  • 79
  • 474
  • 476
  • 1
    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 Sep 16 '13 at 08:22
  • @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. – Benjamin Gruenbaum Sep 16 '13 at 11:19
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.

Community
  • 1
  • 1
Jonathon Reinhart
  • 116,671
  • 27
  • 221
  • 298
  • Nice explanation. Can you say , why the **$("#output").text("button1 start");** will not executed before the **pausecomp(5000);** executes ? – Human Being Sep 16 '13 at 07:03
  • 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. – Jonathon Reinhart Sep 16 '13 at 07:04
  • @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. – Benjamin Gruenbaum Sep 16 '13 at 07:07
  • @BenjaminGruenbaum I look forward to hearing the low-level details, as my answer was done in a pretty hand-waving fashion anyway. – Jonathon Reinhart Sep 16 '13 at 07:08
-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.

Moiz Ahmed
  • 91
  • 5
  • This is counter to what others have said so far. Please see the comments. Are you sure this is correct? – CookieMonster Sep 16 '13 at 06:55
  • 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. – 0xc0de Sep 16 '13 at 06:59
  • This answer is incorrect in any browser that implements the DOM API according to the specification. – Benjamin Gruenbaum Sep 16 '13 at 07:00