2010-06-23 91 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,但是,您可能还想搜索教程或发布后续问题,因为首先处理规格可能很困难。

相关问题