了解 JavaScript 计时器线程问题
我正在开始开发一个 javascript MMORPG,它实际上可以顺利运行。目前,我创建了一个演示来证明我可以移动角色并让他们互相聊天,以及看到彼此实时移动。
现在 Javascript 定时器是我没有广泛使用的东西,但是从什么开始我知道,如果我错了,请纠正我,同时发生多个 setIntervals 并不能很好地工作,因为它都在单个线程上。
假设我想让 10 个不同的人通过使用带有 setInterval 的精灵背景定位来向怪物发射火球——该动画需要 10 个 setInterval 来重新绘制 DOM 以实现精灵背景位置的移动。不会是个大车吧?
我想知道是否有办法解决这一切,也许使用 Canvas,这样动画就可以同时发生,而无需创建事件队列,而且我不必担心计时器。
希望这是有道理的,如果我需要进一步澄清,请告诉我。
I'm starting on a javascript MMORPG that will actually work smoothly. Currently, I created a demo to prove that I can move characters around and have them chat with each other, as well as see eachother move around live.
Now Javascript timers are something I have not used extensively, but from what I know, correct me if I'm wrong, is that having multiple setIntervals happening at the same time doesn't really work well b/c it's all on a single thread.
Lets say I wanted to have 10 different people nuking fireballs at a monster by using sprite background positioning with setInterval -- that animation would require 10 setIntervals doing repainting of the DOM for sprite background-position shifts. Wouldn't that be a big buggy?
I was wondering if there was a way around all this, perhaps using Canvas, so that animations can all happen concurrently without creating an event queue and I don't have to worry about timers.
Hope that makes sense, and please let me know if I need to clarify further.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
多个 setInterval 的问题是双重的。第一个是正如您所指出的,由于浏览器上的所有 JavaScript(当前)都是单线程的,一个计时器的执行可能会阻止下一个计时器的执行。 (工作线程即将推出;Firefox 已经有了它们,Safari 4 [也许还有其他]也是如此。)第二个是计时器按设定的时间间隔发生,但如果您的处理程序是当该间隔到期时仍在运行,第二个间隔将完全跳过。例如,计时器可能会干扰自身。
最后一部分需要更多解释:假设您有一个 10ms 的 setInterval (这是您可以合理预期任何实现执行此操作的最快速度;可能会受到限制,以便它们不会比这更快)。如果您的处理程序花费了 13 毫秒,则应该在开始后 10 毫秒发生的间隔将被完全跳过。
我通常使用
setTimeout
来处理这种事情。当我的处理程序被触发时,我会执行我的工作,然后在处理程序末尾安排下一个事件。然后(在您可以确定的范围内),我知道下一个事件将在该时间间隔内发生。对于您正在做的事情,似乎单个“脉冲”计时器是最好的,可以完成它需要在脉冲上执行的任何操作。脉冲计时器是使用
setInterval
还是setTimeout
是根据您在实际代码中看到的情况进行的判断。The issue with multiple
setInterval
s is twofold. The first is as you indicate, since all Javascript on browsers is (currently) single-threaded, one timer's execution may hold up the next timer's execution. (Worker threads are coming, though; Firefox already has them, as does Safari 4 [and maybe others].) The second is that the timer happens at a set interval, but if your handler is still running when that interval expires, the second interval is completely skipped. E.g., the timer can interfere with itself.That last part needs more explanation: Say you have a setInterval at 10ms (which is the fastest you can reasonably expect any implementation to do it; may are clamped so that they don't go faster than that). If your handler takes 13ms, the interval that should have happened 10ms after it began will be completely skipped.
I usually use
setTimeout
for this kind of thing. When my handler is triggered, I do my work and then schedule the next event at the end of the handler. Then (within the bounds of what you can be certain of), I know the next event will happen at that interval.For what you're doing, it seems like a single "pulse" timer would be best, working through whatever it needs to do on the pulse. Whether that pulse timer uses
setInterval
orsetTimeout
is a judgment call based on what you're seeing with your actual code.给 TJ Crowder +1,答案很完美。我强烈建议学习使用 Canvas 而不是 DOM 节点来制作游戏动画;后者速度慢且有缺陷,并且会在任何重要情况下挂起浏览器。 OTOH,Canvas 速度更快,并且可以进行硬件加速,如果您需要的话,甚至还可以提供 3D 上下文。
+1 to T. J. Crowder, the answer was perfect. I strongly recommend learning to use Canvas over DOM nodes for game animation; the latter is slow and buggy, and will hang the browser in any non-trivial situation. OTOH, Canvas is much faster and can be hardware accelerated, and even has a 3D context if you need it.