2010-06-23 1 views
1

Я хотел бы создать механизм цикла событий в JavaScript/DOM, используя только вызовы dispatchEvent.Являются ли события цикла в JavaScript с использованием document.dispatchEvent возможным?

Например:

document.addEventListener("LoopingEvent", loop, true); 
var loop = function() { 
    doSomeWork(); 
    updateUI(); 
    document.dispatchEvent(loopEvent); 
}; 
var loopEvent = document.createEvent('Events'); 
loopEvent.initEvent("LoopingEvent", true, true); 
document.dispatchEvent(loopEvent); 

При запуске генерируется ошибка OutOfRange стека вызовов. Если я изменю вызов диспетчера обработчика цикла, чтобы использовать задержка window.setTimeout, он будет работать без ошибок.

Просто интересно, если есть способ использовать dispatchEvent цикл бесконечно, не прибегая к setInterval или setTimeout? Преимущество шаблона цикла dispatchEvent заключается в том, что вызовы возникают, когда работа выполняется, а не через заданные интервалы времени.

Заранее спасибо за любые идеи ...

ответ

0

Похоже, вы индуцирования бесконечный цикл, который будет продолжать работать неопределенно долго. Задержка таймера между выполнением необходима, чтобы другие очереди функций в потоке.

Преимущество в шаблоне цикла отправки dispatchEvent заключается в том, что вызовы возникают, когда работа выполняется, а не через заданные интервалы времени.

setTimeout с задержкой 0ms бы добиться этого эффекта, хотя цикл setTimeout или setInterval бы вызвать другой бесконечный цикл должен быть создан, так что по крайней мере, некоторая задержка необходима, как я указывал выше.

0

Я не могу комментировать dispatchEvent(), но что случилось с этой схемой:

function DoSomeWork() 
{ 
    // do work 
    if (moreWorkNeedsDoing) 
    { 
     setTimeout(DoSomeWork, 0); 
    } 
} 

функция будет перебирать «немедленно», пока есть работа.

1

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

Смежные вопросы