以下代码段说明了我的问题。我有一些代码会针对jQuery.trigger
事件调用customeventstart
,然后进行一些密集处理,然后再次针对jQuery.trigger
事件调用customeventstop
。
我希望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');
});
&#13;
<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>
&#13;
我打算使用异步Web Workers解决方案,但我想更好地了解正在发生的事情。
为什么jQuery.trigger
ed事件的处理程序等待或似乎要等到触发代码完成?
答案 0 :(得分:0)
我认为这与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上,单击按钮会导致延迟,然后所有行都会一起显示 - 但是如果查看时间戳,很明显延迟实际发生在“开始密集处理”和“密集处理”之间完成“与Chrome和IE11一样的日志声明(我必须在最大循环中添加0才能在Firefox中看到这一点 - 哇这几天这些事情很快):
"1424713006530: triggering customeventstart" "1424713006530: starting" "1424713006531: starting intensive processing" "1424713007263: intensive processing done" "1424713007263: triggering customeventstop" "1424713007264: stopping"
所以不是事件在延迟后被触发,而是如果主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>