这是setInterval
可以很快成为一个非常糟糕的想法™ 的地方。
问题是这样的:
如果您调用setInterval(lots_O_functions, 15);
将要发生的事情lots_O_functions
,那么它将在 15 毫秒后被调用,但是如果需要 45 毫秒来完成所有这些工作,它不会被中断,相反,您将有两个lots_O_functions
呼叫等待一旦你的第一个完成就运行......
...假设这两个也分别花费 45 毫秒,那么您现在还有 6 个lots_O_functions
电话在排队等待...
那是你想要发生的事情吗?我不知道。就个人而言,我会说大多数时候不是,原因如下:
JS 在单线程上运行。事实上,在绝大多数情况下,浏览器中的几乎所有事情(点击、重新绘制页面上的元素,甚至离开页面并转到其他地方)都与同一个线程相关联。
因此,通过对繁重函数的重叠调用来阻塞线程是不好的™
相反,为什么不使用类似的东西:
var big_state_machine = { /*...*/ },
lots_O_work = function () {
big_state_machine.currentState.jobs.forEach(/*...*/);
/*....... do lots o' work ......*/
var more_work_to_do = /* figure out if you need to rerun lots_O_work */;
if (more_work_to_do) { setTimeout(lots_O_work, 20); }
};
lots_O_work();
现在,它会做它需要做的事情,如果之后还有更多事情要做,它会调用 setTimeout 以在该点之后至少排队20 毫秒。
setTimeout
不像 asleep
或 a wait
,它说:“展望未来 20 毫秒,看看有多少人已经在等待做事......从那里开始,让我排在下一个可用的位置”。
这里的不同之处在于,您在第一个函数完成后 20 毫秒完成,这意味着至少需要 20 毫秒才能发生其他事情(点击、绘画、AJAX 等)。
使用setInterval
,它就像,但不是在事后setTimeout
在下一个可用位置排队,而是将自己设置在队列中,无论它是否准备好(或需要)。
你可以进一步分解它以保持它真正的响应,但这将是一个好的开始。