我已阅读以下主题is-javascript-guaranteed-to-be-single-threaded 那里有一个很好的例子:
<textarea id="log" rows="20" cols="40"></textarea>
<input id="inp">
<script type="text/javascript">
var l= document.getElementById('log');
var i= document.getElementById('inp');
i.onblur= function() {
l.value+= 'blur\n';
};
setTimeout(function() {
l.value+= 'log in\n';
l.focus();
l.value+= 'log out\n';
}, 100);
i.focus();
</script>
输出
log in
blur
log out
而非预期
log in
log out
blur
所以这基本上表明我的blur
上的事件处理程序被触发,这会中断setTimeout回调中代码的执行。我已经阅读了其他一些文章和解释,说明代码不会被中断(run-to-completion principle),除了模态弹出窗口(警报,提示窗口)等一些极端情况。那么为什么它会在示例中被中断呢?
我可以带来的唯一解释是我从代码中手动触发focus
事件,同时执行控制在JS引擎上。如果没有手动触发,则执行代码期间的模糊事件将被浏览器检测到并放入队列中,只有在代码执行完成后(堆栈为空)才会处理该队列。
答案 0 :(得分:1)
如您所链接的问题所述:
当代码执行某些操作时,浏览器会立即触发这些[事件]:
在上面的示例中,关注元素会导致以前具有焦点的元素发生立即blur
事件。此事件未排队,它会立即触发。实际上,focus()
方法直接调用以前关注元素的blur
侦听器。
立即执行此操作非常有用,这样blur
处理程序可以确保可以访问剩余元素的当前状态;我们不想让其他代码有机会先改变字段。