So I answered a question recently and OP asked if I could add the following about DOM events to my answer:
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.
Well, can I add that? Do I know that with DOM events will run one event at a time and will wait for the previous one to finish before the next one starts?
Do I at least know this is always the case in browser JavaScript?
Finding a conclusive answer to this has been surprisingly difficult to be so far, I've expected a "yes" but I just can't find it.
Clarification: I'm not asking about adding other asynchronous handlers inside the handlers, or calling setTimeout or workers and such. All I'm asking is whether or not the order of event handler execution is guaranteed, and that the next one starts only the previous one finished executing ? A good answer would cite a credible source (preferably - a specification). Nothing about threading here.
JavaScript HTML DOM Events. HTML DOM allows JavaScript to react to HTML events: Reacting to Events. A JavaScript can be executed when an event occurs, like when a user clicks on an HTML element.
Event Loop and Single Thread Mechanism in JavaScript. "JavaScript is a single-threaded, non-blocking, asynchronous, concurrent language." Any Javascript book/tutorial has this line etched in their introduction. On top of that this compact line is perplexing. How exactly is Javascript single-threaded? If so, how does it handle multiple API calls?
The event starts its journey at the root of the document, working its way down through each layer of the DOM, firing on each node until it reaches the event target. The job of the capture phase is to build the propagation path, which the event will travel back through in the bubbling phase.
The Financial Times uses this event to detect any images that might have failed to load in an article and instantly hide them. Because the “ DOM Level 3 Events ” specification has redefined the error event to “not bubble,” we can handle the event in one of two ways.
Yes and no, all JS runs on the same thread, except for web workers, which don't have access to the DOM. http://dev.opera.com/articles/view/timing-and-synchronization-in-javascript/
Here's some relevant information on that page
All event handler functions are executed sequentially, and each event is processed completely (including bubbling up through the DOM and performing the default action), before the next event is processed.
However, later on that page, they mention
Race Conditions
Each window (and frame) has its own event queue. In Opera, every window has its own JavaScript thread. This includes windows in iframes. The consequence is that event handlers initiated from different frames might execute at the same time. If these simultaneous scripts modify shared data (like properties in the top window), we have the possibility of race conditions.
Events all are put into an event queue, and all event handling happens within that same thread. Along with all asynchronous callbacks, like XHR and setTimeout
.
Beware of nested events also, since many methods will execute if you fire an event and they could change global state. Example http://jsfiddle.net/rpxZ4/
$('#d1').click(function(){
alert('before ');
$('#d2').trigger('click');
$('#d3').trigger('click');
alert('after ');
});
$('#d2, #d3').click(function() {
alert('clicked ' +this.id);
});
Here are Opera's suggestions for dealing with timing
Well, that actually depends on what do you do in your handler and how do you define 1st handler ended moment?
For example, if you're doing only sync operations in eventHandler1 then you're sure that eventHandler2 won't get triggered before eventHandler1 finishes. the reason is javascript being single threaded.
But, imagine scenario like this: click on button1 triggers eventHandler1 which actually makes ajax request. in that scenario, what do you actually consider as 'end of eventHandler1'? if it is the moment when ajax request returns then certainly eventHandler2 will start (and possible end) execution before eventHandler1 finishes.
To put it short: whenever you do sync-only operations > the order is guaranteed.
http://www.w3.org/TR/DOM-Level-3-Events/#sync-async for example, it says: " Each event in this virtual queue must be delayed until the previous event has completed its propagation behavior, or been canceled."
Well, now we're back to the question 'what type of events are we talking about'? As mentioned before: if it's async events then sure the order is not guaranteed. But the original dilemma was about click event and that one is not async but sync. And for sync events documentation clearly states: Events which are synchronous ("sync events") must be treated as if they are in a virtual queue in a first-in-first-out model, ordered by sequence of temporal occurrence, with respect to other events, to changes in the DOM, and to user interaction.
yep, no guarantees. now add javascript being single-threaded into play and you can't get them executing at the same time. but yes, speaking of DOM strictly - there is no guarantee whatsoever which one will happen before.
just one more comment... you might have exactly the same DOM but accessed from Java multi-thread environment. What then?:) then you have to implement your own thread-safe async events handling because you're no more 'protected' by single thread environment as you have with javascript. So, the conclusion, as i see it is that DOM specs does require that sync events are fifo implemented. for async events execution depends on stack/thread implementation. in Javascript, that means that 2 handlers can't overlap but in Java e.g. doesn't have to mean.
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