Я всегда думал, что, поскольку JavaScript был однопоточным, я мог присоединять обработчики событий, не беспокоясь о том, что обработчики выполняются, когда я был в середине выполнения кода. К моему удивлению, я обнаружил, что они могут. В соответствии с этим ответом диалоговое окно «Сценарий не отвечает» может вызывать события , пока сценарий еще выполняется.
Я проверил это с помощью следующего кода:
<script>
function loop() {
var cond;
onblur = function (event) {
cond = false;
};
cond = true;
while (cond)
;
alert('loop exited!');
}
</script>
<button onclick="loop()">loop()</button>
(jsFiddle)
В Firefox 11.0 функция выводит «цикл завершен» после нажатия кнопки «Продолжить». Цикл кажется приостановленным, и события могут выполняться. Это похоже на Unix-сигнал , который временно меняет контекст целевого потока. Но это намного опаснее, поскольку позволяет изменять внешнее состояние.
Это ошибка? Должен ли я больше не зависеть от модели JavaScript с единым потоком выполнения и гарантировать, что все мои сценарии являются входящими повторно? Или это недостаток, который не стоит искать, несмотря на то, что крупный браузер позволяет этому случиться?