dispatchEvent
отправляет событие синхронно с целью, поэтому при использовании dispatchEvent
кадры обработчика событий накапливаются в стеке и, в конечном счете, переполняются.
Если вы хотите просто «петли навсегда», у вас есть несколько вариантов. Какой выбор правильный, зависит от того, как вы хотите, чтобы ваш код взаимодействовал с другими событиями. Я замечаю, что ваш код предполагает, что он будет updateUI()
. Ну, ваш обработчик событий должен периодически возвращаться в цикл событий браузера, чтобы он мог нарисовать обновленный пользовательский интерфейс. Использование setTimeout(loop, 0);
является хорошим способом для достижения этой цели:
function loop() {
doSomeWork();
updateUI();
setTimeout(loop, 0);
}
loop(); // get things started
Вызов setTimeout
будет вернуться до loop
вызывается снова; то браузер снова вызовет loop
. Между звонками до loop
браузер может запускать другой код, например, рисовать изменения в пользовательском интерфейсе или вызывать другие обработчики событий в ответ на клики и другие события.
Если вы хотите, вы можете сделать свою петлю медленнее, увеличив задержку от 0 мс до чего-то большего. Это может быть полезно, если ваш цикл выполняет анимацию.
Если вы хотите, чтобы ваш цикл остановился, тогда не вызывайте setTimeout
, и он не будет вызываться снова.
Теперь вот альтернативная техника:
Если вы используете относительно последнюю версию Firefox, Chrome или Safari, вы можете использовать новую функцию рабочих, чтобы запустить цикл. Рабочие имеют свой собственный цикл обработки событий, так что это нормально, чтобы написать такой код:
// worker code
while (true) {
doSomeWork();
// post messages to update the UI
}
Рабочих работать отдельно от других сценариев; чтобы выталкивать результаты на страницу, вам нужно использовать функцию, называемую postMessage
. Здесь the relevant spec,, однако вы можете также искать учебники или оставлять вопрос о последующих действиях, потому что сначала отключение спецификации может быть затруднено.