Andy
Andy

Reputation: 8692

setTimeout and UIEvent order

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?

Upvotes: 2

Views: 441

Answers (2)

jfriend00
jfriend00

Reputation: 708136

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);
});

Upvotes: 3

Joshua Dannemann
Joshua Dannemann

Reputation: 2080

After doing a little testing, I have to edit my answer because I was incorrect. Yes, UI events do take precedence over timeout. For timeout, it appears that no matter what order it is set up, UI events happen first.

Upvotes: 0

Related Questions