gpt4 book ai didi

javascript - JavaScript 中是否可以使用 document.dispatchEvent 循环事件?

转载 作者:行者123 更新时间:2023-11-28 02:54:03 31 4
gpt4 key购买 nike

我想仅使用dispatchEvent调用在JavaScript/DOM中创建一个事件循环机制。

例如:

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 循环模式的优点是,调用在工作完成时发生,而不是在设定的时间间隔内发生。

预先感谢您提供任何见解...

最佳答案

dispatchEvent 将事件同步发送到目标,因此当您使用 dispatchEvent 时,事件处理程序帧会在堆栈上累积并最终溢出。

如果您只想“永远循环”,您有几种选择。哪个选择是正确的取决于您希望代码如何与其他事件交互。我注意到您的代码表明它将updateUI()。那么,您的事件处理程序需要定期返回浏览器的事件循环,以便它可以绘制更新的 UI。使用 setTimeout(loop, 0); 是实现此目的的好方法:

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

setTimeout的调用将在再次调用loop之前返回;然后浏览器将再次调用loop。在对循环的调用之间,浏览器可能会运行其他代码,例如在 UI 中绘制更改,或调用其他事件处理程序以响应点击和其他事件。

如果您愿意,可以通过将延迟从 0 毫秒增加到更大的值来使循环运行得更慢。如果您的循环正在执行动画,这可能很有用。

如果您希望循环停止,请不要调用 setTimeout,它不会再次被调用。

现在这是一种替代技术:

如果您使用的是相对较新版本的 Firefox、Chrome 或 Safari,您可以使用名为“workers”的新功能来运行循环。 Workers 有自己的事件循环,因此可以编写如下代码:

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

Workers 与其他脚本分开运行;要将结果推送到页面本身,您需要使用名为 postMessage 的函数。这是the relevant spec,但是,您可能还想搜索教程或发布后续问题,因为一开始按照规范进行工作可能会很困难。

关于javascript - JavaScript 中是否可以使用 document.dispatchEvent 循环事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3101658/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com