2010-06-23 38 views
1

我想在JavaScript/DOM中僅使用dispatchEvent調用創建事件循環機制。是否可以使用document.dispatchEvent在JavaScript中循環事件?

例如:

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與0毫秒會達到這樣的效果的延遲,雖然循環setTimeoutsetInterval將導致創建另一個無限循環,所以至少一些延遲是必要的,因爲我上面所指出的。

0

我不能對dispatchEvent(),但有什麼不對這種模式發表評論:

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

功能將迭代「立即」只要有工作要做。

1

dispatchEvent將事件同步發送到目標,所以當您使用dispatchEvent時,事件處理程序幀在堆棧上累積並最終溢出。

如果你想簡單地「循環永久」,你有幾個選擇。哪種選擇是正確的取決於你希望你的代碼如何與其他事件交互。我注意到你的代碼暗示它將會是updateUI()。那麼,您的事件處理程序需要定期返回到瀏覽器的事件循環,以便它可以繪製更新的UI。使用setTimeout(loop, 0);是一個很好的方式來實現這一目標:

function loop() { 
    doSomeWork(); 
    updateUI(); 
    setTimeout(loop, 0); 
} 
loop(); // get things started 

之前loop再次調用setTimeout的調用將返回;那麼瀏覽器將再次調用loop。在對loop的調用之間,瀏覽器可以運行其他代碼,例如在UI中繪製更改,或者調用其他事件處理程序來響應點擊和其他事件。

如果你想要的話,你可以通過增加從0毫秒到更大的延遲來讓你的循環運行更慢。如果你的循環正在做動畫,這可能會很有用。

如果你想循環停止,那麼不要調用setTimeout,它不會再被調用。

現在這裏是一種替代技術:

如果您使用的是相對較新的Firefox,Chrome或Safari的版本,你可以使用一個新功能叫工人來運行你的循環。工人有自己的事件循環,所以它是確定這樣寫代碼:

// worker code 
while (true) { 
    doSomeWork(); 
    // post messages to update the UI 
} 

工人從其他腳本單獨運行;要將結果推入頁面本身,您需要使用名爲postMessage的函數。這裏是the relevant spec,但是,您可能還想搜索教程或發佈後續問題,因爲首先處理規格可能很困難。

相關問題