setTimeout和UIEvent命令

时间:2015-08-21 20:58:05

标签: javascript javascript-events settimeout uievent eventqueue

如果一堆UIEvents由于脚本中的一些长时间运行的方法排队,并且在方法I setTimeout(myfunc, 0)的末尾,相对于处理程序将调用myfunc的顺序是什么对于以前排队的事件?是否保证在处理完所有先前排队的事件后调用它?

2 个答案:

答案 0 :(得分:2)

浏览器中的大多数事件都是通过中央事件队列以FIFO顺序(先进先出)处理的。某些UI事件(如mousemove事件)将折叠,以便您获得最新状态,而不一定是所有中间事件。

所以,问题是当鼠标事件进入JS事件队列时。我不确定这是如何工作的,所以我构建了几个测试演示。我发现答案取决于。如果UI事件正在占用JS线程,那么看起来其他UI事件不会进入计时器前的队列,但是如果UI事件结束并且其他一些操作(不在UI上) )占用CPU,然后evnets按正确的FIFO顺序排队。所以,似乎"它取决于" (在我目前为止测试过的Chrome中)。

我会在一秒钟内发布演示链接...

This demo表示如果CPU占用活动不响应按钮点击,那么在setTimeout()计划触发之前发生的其他按钮点击将在{{1}之前得到处理}:

setTimeout()

但是,this demo在按钮点击事件处理程序本身中发生CPU占用的情况显示相反的情况。 long click click click timeout 计划发生之前发生的点击在此之前未得到处理。

setTimeout()

现在,我在Firefox中运行了这两个版本,发现在两种情况下,Firefox都按FIFO顺序处理事件(按实际发生的顺序)。对于上面的第二个演示,这与Chrome不同。

现在,我在IE中运行这些,发现IE总是在UI事件之前处理long timeout click click click - 与Firefox和Chrome不同。

因此,这些测试在三种不同的浏览器中显示三种不同的结果。

总结结果:

setTimeout()

作为参考,这里是在按钮点击事件处理程序中占用CPU的测试用例:

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)

而且,这是在按钮客户端事件处理程序完成后占用CPU的测试用例。

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

答案 1 :(得分:0)

经过一些测试后,我必须编辑我的答案,因为我不对。是的,UI事件优先于超时。对于超时,似乎无论设置什么顺序,UI事件都会先发生。