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