为什么事件处理程序要等到触发代码完成执行
Why does event handler wait until triggering code completes execution?
下面的片段说明了我的问题。我有一些代码,它为customeventstart
事件调用jQuery.trigger
,然后进行一些密集处理,然后为customeventstop
事件再次调用jQuery.trigger
。
我期望customeventstart
的事件处理程序立即执行。但是,在控制台显示customeventstart
处理程序的结果之前有一个明显的延迟。事件处理程序似乎直到触发代码完成执行后才会被调用。
注意:您可以根据机器的处理能力调整代码段中循环的迭代次数,以延长/缩短延迟。
btn = $('#btn');
btn.on('click', function() {
btn.trigger('customeventstart');
// intensive/time-consuming processing
for (var i = 0; i < 100000000; ++i) {
'string' + 'concatenation';
}
console.log('intensive processing done');
btn.trigger('customeventstop');
});
btn.on('customeventstart', function() {
console.log('starting');
});
btn.on('customeventstop', function() {
console.log('stopping');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">This may take a while</button>
我计划使用异步Web Workers解决方案,但我想更好地了解正在发生的事情。
为什么jQuery.trigger
ed事件的处理程序要等待或似乎要等到触发代码完成
我认为这与Firefox(和Firebug)中的console.log
实现有关,而不是与事件的实际时间有关。
我尝试了对您的代码片段进行以下修改,基本上只添加了Date.now
和几个控制台日志语句:
btn = $('#btn');
btn.on('click', function() {
console.log(Date.now() + ': triggering customeventstart');
btn.trigger('customeventstart');
// intensive/time-consuming processing
console.log(Date.now() + ': starting intensive processing');
for (var i = 0; i < 100000000; ++i) {
'string' + 'concatenation';
}
console.log(Date.now() + ': intensive processing done');
console.log(Date.now() + ': triggering customeventstop');
btn.trigger('customeventstop');
});
btn.on('customeventstart', function() {
console.log(Date.now() + ': starting');
});
btn.on('customeventstop', function() {
console.log(Date.now() + ': stopping');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">This may take a while</button>
对我来说:
-
在Chrome和IE11上,点击按钮会导致前三条日志语句几乎即时记录(通过"开始密集处理"),然后是延迟,然后是其余行。线路上的时间戳证明了顺序和时间。
-
在Firefox上,单击该按钮会导致延迟,然后所有行一起出现—但如果你看一下时间戳,很明显,延迟实际上发生在"开始密集处理"answers"完成密集处理"日志语句之间,就像Chrome和IE11一样(我不得不在循环最大值上加一个0才能在Firefox中看到这一点—哇,现在这些事情很快):
"1424713006530:触发customeventstart"1424713006530:正在启动"1424713006531:开始密集处理"1424713007263:已完成密集处理"1424713007263:触发customeventstop"1424713007264:正在停止"
因此,这并不是说事件在延迟后被触发,而是如果主UI线程繁忙,Firefox的console.log
实现似乎会被搁置。
这与通常的情况非常相似,在这种情况下,当主UI线程繁忙时,浏览器可能不会更新页面的显示。例如,在下面的片段中,我们在进行密集处理时(根本不使用任何自定义事件)将按钮的背景变为红色,然后在完成后将其恢复;但是在大多数浏览器上,你根本看不到按钮的背景变化,即使在处理过程中有足够的时间:
btn = $('#btn');
btn.on('click', function() {
console.log(Date.now() + ': turning button background red');
btn.css('background-color', 'red');
// intensive/time-consuming processing
console.log(Date.now() + ': starting intensive processing');
for (var i = 0; i < 100000000; ++i) {
'string' + 'concatenation';
}
console.log(Date.now() + ': intensive processing done');
console.log(Date.now() + ': restoring button background');
btn.css('background-color', '');
});
(Look in the console.)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">This may take a while</button>
- setTimeout函数能否在其前面的代码执行之前激发
- 延迟代码执行,直到下载完成
- 奇怪的javascript代码执行顺序
- 将字符串作为一段 HTML/javascript 代码执行
- 使用AngularJS,如何在视图和控制器同步特定更改后触发代码执行
- onKeyUp 导致代码执行两次
- JQuery:将参数传递给插件以限制代码执行
- JavaScript代码执行时间
- 基本的JavaScript代码执行
- JavascriptCore:从本机代码执行JavaScript定义的回调函数
- 脚本标记的位置会影响代码执行
- 页面脚本未使用 Salesforce Web-to-Lead 代码执行
- GM_xmlhttpRequest 成功回调“onload”未为注入的代码执行
- 停止所有代码执行,直到 IFrame 完全加载
- 纯 Javascript 代码执行停止混合应用程序中的离子加载指示器
- Javascript代码执行顺序
- Javascript:在嵌套函数中使用条件语句停止代码执行
- Node.js代码执行顺序
- 什么触发JavaScript代码执行
- onreadystatechange导致php代码执行两次