If a bunch of UIEvents are queued up because of some long-running method in a script, and at the end of the method I setTimeout(myfunc, 0)
, what order will myfunc
get called in relative to handlers for the previously queued events? Is it guaranteed to be called after all previously queued events get handled?
Most events in the browser are processed in FIFO order (first in, first out) via a central event queue. Some UI events such as mousemove events are collapsed so you get the latest state, not necessarily all the in-between events.
So, the question is really when the mouse event gets into the JS event queue. I wasn't really sure how this worked so I built a couple test demos. What I found was that the answer depends. If a UI event is what is hogging the JS Thread, then it looks like the other UI events don't get into the queue in front of the timer, but if the UI event finishes and some other action (not on the UI) hogs the CPU, then the evnets are queued in proper FIFO order. So, it appears that "it depends" (in Chrome which is what I have tested so far).
I will post links to the demos in a second...
This demo shows that if the CPU hogging activity is not in response to a button click, then other button clicks that occur before the setTimeout()
is schedule to fire will get processed before the setTimeout()
:
long
click
click
click
timeout
But, this demo where the CPU hogging happens in the button click event handler itself shows the opposite. The clicks that happened before the setTimeout()
was scheduled to fire did not get processed before it.
long
timeout
click
click
click
Now, I ran these both in Firefox and found that in both cases Firefox processes the events in FIFO order (in the order they actually happened). For the second demo above, this is different than Chrome.
Now, I ran these both in IE and found that IE always processes the setTimeout()
before the UI events - different than both Firefox and Chrome.
So, these tests show three different results in three different browsers.
Summarizing Results:
Browser Hog CPU in Event Handler Hog CPU after Event Handler
---------------------------------------------------------------------
Chrome 44 timeout first (not FIFO) FIFO clicks first
Firefox 39 FIFO clicks first FIFO clicks first
IE 11 timeout first (not FIFO) timeout first (not FIFO)
For reference, here's the test case that hogs the CPU in the button click event handler:
document.getElementById("test").addEventListener("click", function() {
log("click");
});
document.getElementById("long").addEventListener("click", function() {
log("long");
setTimeout(function() {
log("timeout");
}, 1900)
// hhog the CPU here before the event handler finishes
var t = Date.now();
while (Date.now() - t < 2000) {}
});
And, here's the test case that hogs the CPU after the button client event handler has finished.
document.getElementById("test").addEventListener("click", function() {
log("click");
});
document.getElementById("long").addEventListener("click", function() {
log("long");
// schedule a setTimeout
setTimeout(function() {
log("timeout");
}, 1900)
// hog the CPU, but after the UI event has finished
setTimeout(function() {
// spin for 2 seconds to hog the JS thread
var t = Date.now();
while (Date.now() - t < 2000) {}
}, 1);
});