Javascript setInterval 方法是(至少)等待两次执行特定代码之间的指定间隔,还是在完成前一次执行和开始下一次执行之间等待该间隔?
(或者,当与 Java 的ScheduledExecutorService
方法进行比较时 - setInterval 是否类似于scheduleAtFixedRate()
或更确切地说scheduleWithFixedDelay()
?)
Javascript setInterval 方法是(至少)等待两次执行特定代码之间的指定间隔,还是在完成前一次执行和开始下一次执行之间等待该间隔?
(或者,当与 Java 的ScheduledExecutorService
方法进行比较时 - setInterval 是否类似于scheduleAtFixedRate()
或更确切地说scheduleWithFixedDelay()
?)
如果您setInterval
以1000毫秒的间隔调用并且回调代码需要100毫秒才能运行,则下一个回调将在900毫秒后执行。
如果回调需要1050毫秒,则下一个将在第一个完成后立即启动(延迟50毫秒)。这种延迟将不断累积。
所以在 Java 世界中,这类似于scheduleAtFixedRate()
. 如果您需要scheduleWithFixedDelay()
行为,则必须在setTimeout()
每次完成时使用并重新安排回调:
function callback() {
//long running code
setTimeout(callback, 1000);
}
setTimeout(callback, 1000);
上面的代码将在完成后恰好等待 1000 毫秒,callback()
然后再重新启动,无论运行多长时间。
这个答案包括来自 jfriend00 下面评论的帮助。
Javascript 是单线程的,所以同一个函数不能同时运行两次。但是 setInterval 延迟不考虑运行该函数需要多长时间。
例如,假设您的 setInterval 函数需要 500 毫秒才能运行,而您的延迟是 1000 毫秒。这将导致函数再次启动之前有 500 毫秒的延迟。
正如您在这个 jsFiddle 测试用例中看到的那样,setInterval 尝试保持时间间隔,无论在时间间隔上运行的代码需要多长时间,只要该代码花费的时间少于设置的时间间隔。因此,如果您将间隔设置为 5 秒,并且在每个间隔上运行的代码需要 200 毫秒,则每个间隔仍应相隔 5 秒(或者尽可能接近单线程 javascript 引擎可以使其达到 5 秒)。
另一方面,如果您在每个间隔上运行的代码花费的时间比间隔时间本身执行的时间长,因为javascript是单线程的,那么下面的间隔将不会按时开始,并且会因为第一个的时间溢出而延迟间隔的代码。
通过调整延迟时间,可以在这个工作测试用例中看到这两种情况。
这里的工作测试用例:http: //jsfiddle.net/jfriend00/kGQsQ/