gpt4 book ai didi

javascript - 为什么事件处理程序要等到触发代码完成执行?

转载 作者:行者123 更新时间:2023-11-28 07:35:18 25 4
gpt4 key购买 nike

以下片段说明了我的问题。我有一些代码为 customeventstart 事件调用 jQuery.trigger,然后进行一些密集处理,然后再次调用 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');
});
<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 事件的处理程序会等待或似乎等待触发代码完成?

最佳答案

我相信这与 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 一样,“done”日志语句(我必须在循环最大值中添加 0 才能在 Firefox 中看到这一点 - 哇,这些天这些东西太快了):

"1424713006530: triggering customeventstart""1424713006530: starting""1424713006531: starting intensive processing""1424713007263: intensive processing done""1424713007263: triggering customeventstop""1424713007264: stopping"

So it's not that the event is being triggered after a delay, but that Firefox's console.log implementation appears to be held up if the main UI thread is busy.

This is very similar to the usual situation where the browser may not update the page's display while the main UI thread is busy. For instance, in the following snippet we turn the background of the button red while the intensive processing is going on (without using any custom events at all), then restore it when done; but on most browsers, you never see the button's background change at all even though there's plenty of time while the processing is happening:

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>

关于javascript - 为什么事件处理程序要等到触发代码完成执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28678763/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com