解决方案
他们基本上是试图做同样的事情,但setInterval
方法会比setTimeout
方法更准确,因为setTimeout
等待1000毫秒,运行功能,然后将另一个超时。因此,等待期间实际上比1000毫秒多一点(或更多,如果你的功能需要很长的时间来执行)。
Altough有人可能会认为setInterval
将执行究竟每1000ms的,它也将推迟,因为JavaScript是不是多线程的语言,这意味着,重要的是要注意的是setInterval
- 如果有是脚本运行的其他部分 - 的间隔将必须等待到结束
在此小提琴,则可以清楚地看到,在超时会落后,而间隔几乎所有的时间几乎1个呼叫/秒(该脚本试图做的)。如果在顶部改变速度可变的东西小像20(这意味着它将尝试运行每秒50次),则间隔将永远不会完全达到每秒50次迭代的平均值。
在延迟几乎总是可以忽略不计,但如果你正在编写一些真正精确,你应该去一个的自调节计时器的(基本上是基于超时计时器,不断调整自身的延迟它的创建)
其他提示
是否有任何差异?
是。超时执行的setTimeout()被调用后,在一定量的时间;一个时间间隔先前的时间间隔发射后执行一定量的时间。
如果您的doStuff()函数需要一段时间来执行你会发现其中的差别。例如,如果我们表示与.
到的setTimeout / setInterval的一个呼叫,与*
和JavaScript执行与[-----]
代码超时/间隔的焙烧时,时间线如下:
Timeout:
. * . * . * . * .
[--] [--] [--] [--]
Interval:
. * * * * * *
[--] [--] [--] [--] [--] [--]
接下来的并发症是如果时间间隔触发而JavaScript是已经忙于什么事情(如处理前一个间隔)。在这种情况下,间隔记住的,只要前面的处理程序结束和控制返回给浏览器发生。因此,例如用于doStuff()过程,有时短([ - ]),有时长([-----]):
. * * • * • * *
[-] [-----][-][-----][-][-] [-]
•表示的间隔点火,可能不能执行它的代码马上,被做了代替悬而未决。
所以间隔尝试“赶上”取回如期进行。但是,他们不排队彼此顶部一个:有只能永远是一个执行每间隔悬而未决。 (如果他们都排队,浏览器将会剩下优秀处决不断扩展列表!)
. * • • x • • x
[------][------][------][------]
x表示的间隔点火,可能无法执行或进行挂起,所以不是被丢弃。
如果您的doStuff()函数惯常需要更长的时间比设定为它的时间间隔来执行,浏览器将吃100%的CPU试图为其服务,并且可以变得不太敏感。
哪你使用,为什么?
双链超时给出的自由时间来浏览器有保证的时隙;间隔试图确保它正在运行尽可能接近其预定的时间执行的功能,在浏览器的用户界面的可用性为代价的。
我会考虑一次性的动画,我想尽可能平稳,而链接的超时是会发生的,而在页面加载的所有时间正在进行的动画更有礼貌的间隔。对于要求较低的用途(如一个简单的更新器,每30秒或东西烧成),可以安全地使用任一。
在浏览器兼容性方面,早的setTimeout setInterval的,但你今天将满足所有的浏览器支持。多年最后失散的是IE Mobile在WinMo的<6.5,但希望那也是现在在我们身后。
的setInterval()
setInterval()
是具有重复运行达到间隔时一个指定的脚本的天然能力的时间间隔基于代码执行方法。它应该的不的嵌套到它的回调函数由脚本作者,使其循环,因为它的的默认循环的。这将保持在发射的时间间隔,除非你叫clearInterval()
。
如果要循环代码动画或上的时钟滴答,然后使用setInterval()
。
function doStuff() {
alert("run your code here when time interval is reached");
}
var myTimer = setInterval(doStuff, 5000);
的setTimeout()
setTimeout()
是,将执行一个脚本基于时间的代码执行方法只的 一次 强>到达的时间间隔时。它会的不的再次除非你通过嵌套调用运行函数中的setTimeout()
对象是齿轮环脚本重复。如果面向循环,它将保持在发射的时间间隔,除非你叫clearTimeout()
。
function doStuff() {
alert("run your code here when time interval is reached");
}
var myTimer = setTimeout(doStuff, 5000);
如果你想要的东西在一段指定的时间后一次发生,然后使用setTimeout()
。这是因为它仅执行达到指定的间隔时,一次。
在的setInterval可以更容易地取消你的代码的将来执行。如果你使用的setTimeout,你必须跟踪计时器ID的情况下,要取消其稍后。
var timerId = null;
function myTimeoutFunction()
{
doStuff();
timerId = setTimeout(myTimeoutFunction, 1000);
}
myTimeoutFunction();
// later on...
clearTimeout(timerId);
与
function myTimeoutFunction()
{
doStuff();
}
myTimeoutFunction();
var timerId = setInterval(myTimeoutFunction, 1000);
// later on...
clearInterval(timerId);
我觉得setTimeout
方法更容易,如果你想取消超时使用方法:
function myTimeoutFunction() {
doStuff();
if (stillrunning) {
setTimeout(myTimeoutFunction, 1000);
}
}
myTimeoutFunction();
此外,如果事情将在功能出问题就只停留在第一时间错误重复,而不是重复错误的每一秒。
在非常不同的是在它们的目的。
setInterval()
-> executes a function, over and over again, at specified time intervals
setTimeout()
-> executes a function, once, after waiting a specified number of milliseconds
这是如此简单
更精细的细节在这里 http://javascript.info/tutorial/settimeout-setinterval
在运行里面的setInterval,这比timeout-工作更多的时间>浏览器将卡住的一些功能。 点击 结果 - 例如,<强> doStuff()强>需要1500秒。要执行与这样做:的的setInterval(doStuff,1000); 强> 结果,1)浏览器中运行的 doStuff()强>这需要1.5秒。要被执行; 结果,2)后〜1秒它试图运行的 doStuff()强>一次。但以前的 doStuff()仍executed->所以浏览器会将此运行队列(第一完成后运行)。 结果,3,4,...)相同的添加到执行下一迭代的队列,但是从先前的 doStuff()强>仍在进行中... 结果的作为result-浏览器被卡住。强> 点击 结果为了防止这种现象,最好的办法是运行的里面的setTimeout的setTimeout效仿的setInterval 。 点击要纠正超时之间的setTimeout调用,您可以使用自我纠错替代JavaScript的的setInterval 技术。
我使用的setTimeout。
显然,不同的是setTimeout的调用该方法一次,setInterval的称之为repeatdly。
下面是一个很好的文章说明的区别:教程: JavaScript的定时器,具有的setTimeout和setInterval
我做setInterval(func, milisec)
的简单的测试,因为我很好奇时功能时消耗比间隔持续时间大于会发生什么。
setInterval
将的通常强>时间表下一迭代刚刚之后的开始前一次迭代的,的除非函数仍在进行中即可。如果是这样,setInterval
将等待,直到函数结束。一旦它发生时,该功能将立即再次发射 - 没有等待按计划下一次迭代(因为这将是条件下无时间超过功能)。还有一个平行重复运行的任何境遇。
我已经在Chrome V23测试此。我希望这是在所有现代浏览器实现的确定性。
window.setInterval(function(start) {
console.log('fired: ' + (new Date().getTime() - start));
wait();
}, 1000, new Date().getTime());
控制台输出:
fired: 1000 + ~2500 ajax call -.
fired: 3522 <------------------'
fired: 6032
fired: 8540
fired: 11048
在wait
函数仅仅是一个螺纹阻挡帮手 - 同步AJAX调用,其在服务器侧恰恰的 2500毫秒强>处理:
function wait() {
$.ajax({
url: "...",
async: false
});
}
您的代码将有不同的执行intevals,并在某些项目,如在线游戏这是不能接受的。首先,你应该怎么做,要与它们进行intevals你的代码的工作,你应该改变“myTimeoutFunction”这样的:
function myTimeoutFunction()
{
setTimeout(myTimeoutFunction, 1000);
doStuff();
}
myTimeoutFunction()
此变化后,将等于
function myTimeoutFunction()
{
doStuff();
}
myTimeoutFunction();
setInterval(myTimeoutFunction, 1000);
但是,你仍然没有稳定的结果,因为JS是单线程的。现在,如果JS线程会很忙的东西,它不会是能够执行回调函数,并执行将被推迟2-3毫秒。是你必须每秒60个处决,并在每次有随机1-3秒的延迟时间,这是绝对不能接受的(一分钟之后这将是大约7200毫秒的延迟),我可以建议,使用这样的:
function Timer(clb, timeout) {
this.clb = clb;
this.timeout = timeout;
this.stopTimeout = null;
this.precision = -1;
}
Timer.prototype.start = function() {
var me = this;
var now = new Date();
if(me.precision === -1) {
me.precision = now.getTime();
}
me.stopTimeout = setTimeout(function(){
me.start()
}, me.precision - now.getTime() + me.timeout);
me.precision += me.timeout;
me.clb();
};
Timer.prototype.stop = function() {
clearTimeout(this.stopTimeout);
this.precision = -1;
};
function myTimeoutFunction()
{
doStuff();
}
var timer = new Timer(myTimeoutFunction, 1000);
timer.start();
这个代码将保证稳定的执行周期。即使线程会很忙,你的代码将后1005个mseconds下次就会有超时995毫秒被执行,而结果将是稳定的。
要看看它有点不同:setInterval的确保了一个代码在每个给定的时间间隔运行(即1000毫秒,或多少指定)而设置的setTimeout它“等待直到”它运行的代码的时间。并且,因为它需要额外的毫秒运行的代码,它增加了高达1000毫秒,因此,在的setTimeout不精确倍再次运行(超过1000毫秒)。
例如,定时器/倒计时不与setTimeout的进行,它们与setInterval的完成,以确保它不延迟和代码运行在准确的给定的间隔。
两者的setInterval和setTimeout的回报,你可以用它来取消执行,也就是说,超时被触发前的定时器ID。要取消你打电话或者clearInterval或clearTimeout这样的:
var timeoutId = setTimeout(someFunction, 1000);
clearTimeout(timeoutId);
var intervalId = setInterval(someFunction, 1000),
clearInterval(intervalId);
此外,当您离开页面或关闭浏览器窗口中的超时被自动取消。
好了,setTimeout的是在一种情况下更好,因为我刚才的教训。我总是用setInterval的,这是我留下来在后台运行了半个多小时。当我切换回该选项卡,(在其上使用的代码)的幻灯片被改变非常迅速,而不是,它应该有每隔5秒。它其实我更多的测试再次发生,无论是浏览器的故障与否并不重要,因为setTimeout的这种情况是完全不可能的。
当您运行下面的JavaScript您可以验证自己bobince答案或查看的jsfiddle
<div id="timeout"></div>
<div id="interval"></div>
var timeout = 0;
var interval = 0;
function doTimeout(){
$('#timeout').html(timeout);
timeout++;
setTimeout(doTimeout, 1);
}
function doInterval(){
$('#interval').html(interval);
interval++;
}
$(function(){
doTimeout();
doInterval();
setInterval(doInterval, 1);
});
的差别是明显的在控制台:
只是添加到什么已经说过,但代码的setTimeout的版本也将达到Maximum call stack size
将从停止工作。由于没有基本情况的递归函数来停止,所以你不能有它运行的永久。的
我认为SetInterval
和SetTimeout
是不同的。 SetInterval
根据时间设置而执行所述块,SetTimeout
执行的代码块一次。
尝试这些代码集的超时倒计时秒后:
setInterval(function(e){
alert('Ugbana Kelvin');
}, 2000);
和然后尝试
setTimeout(function(e){
alert('Ugbana Kelvin');
}, 2000);
您可以看到不同的自己。