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
.Вот соответствующая спецификация, , однако вы также можете поискать учебники или опубликовать дополнительный вопрос, потому что сначала отработать спецификацию может быть сложно.