最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Do DOM Events Always Run Single Threaded? - Stack Overflow

programmeradmin0浏览0评论

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.

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.

Share Improve this question edited May 2, 2021 at 21:55 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Sep 16, 2013 at 15:51 Benjamin GruenbaumBenjamin Gruenbaum 277k89 gold badges520 silver badges517 bronze badges 13
  • depends on what the event handler does. if it defers a new script loading, that doesn't have to be finished before the next event handler bubbles up... even just a setTimeOut can hop the order. – dandavis Commented Sep 16, 2013 at 16:01
  • When you add a script it too will wait for it's turn to run. It doesn't break the event loop model. If you use a setTimeout you are intentionally manipulating the order. Keep in mind that the 2nd parameter to setTimeout is a best effort; if you pass 1000 there is no guarantee it will run exactly 1 second from now. It's mon that you'll see it skew, especially over long periods. – Halcyon Commented Sep 16, 2013 at 16:03
  • Yes the browser is supposed to honor a single-threaded model within the JavaScript code. Web Workers is the only way to run code concurrently. However, I've found Firefox to have some bugs with this. If you are making synchronous ajax requests, and you are also listening to a websocket, Firefox will incorrectly call your websocket message handler when a message arrives even though your JavaScript code is currently blocked on the ajax request. Totally messes everything up when this happens. – Brandon Commented Sep 16, 2013 at 16:25
  • possible duplicate of Is javascript guaranteed to be single-threaded? – Bergi Commented Sep 16, 2013 at 16:34
  • @Bergi no, (and I actually referenece that question in the one I linked to). What I'm asking is - does the DOM API guarantee that event handlers are executed one after the other and the next one only after the last one pleted? It's not about JS in general or even timers for that manner. It's about the DOM events api. – Benjamin Gruenbaum Commented Sep 16, 2013 at 21:27
 |  Show 8 more ments

2 Answers 2

Reset to default 7

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./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 pletely (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/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

  • Don't have long-running scripts.
  • Don't use synchronous XMLHttpRequests.
  • Don't let scripts initiated from different frames manipulate the same global state.
  • Don't use alert boxes for debugging, as they might change the logic of the program pletely.

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.

Added from ments:

http://www.w3/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 pleted 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 ment... 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.

发布评论

评论列表(0)

  1. 暂无评论