开发者社区> 技术小胖子> 正文

setTimeout与setInterval区别

简介:
+关注继续查看

window对象有两个主要的定时方法,分别是settimeout 和 setinteval  他们的语法基本上相同,但是完成的功能取有区别。 

settimeout方法是定时程序,也就是在什么时间以后干什么。干完了就拉倒。 

setinterval方法则是表示间隔一定时间反复执行某操作。 

如果用settimeout实现setinerval的功能,就需要在执行的程序中再定时调用自己才行。如果要清除计数器需要 根据使用的方法不同,调用不同的清除方法:

这两种方法可能看起来非常像,而且显示的结果也会很相似,不过两者的最大区别就 是,setTimeout方法不会每隔5秒钟就执行一次showTime函数,它是在每次调用setTimeout后过5秒钟再去执行showTime函 数。这意味着如果showTime函数的主体部分需要2秒钟执行完,那么整个函数则要每7秒钟才执行一次。而setInterval却没有被自己所调用的 函数所束缚,它只是简单地每隔一定时间就重复执行一次那个函数。

如果要求在每隔一个固定的时间间隔后就精确地执行某动作,那么最好使用setInterval,而如果不想由于连续调用产生互相干扰的问题,尤其是每次函数的调用需要繁重的计算以及很长的处理时间,那么最好使用setTimeout。

 

setTimeout和setInterval这两个函数, 大家肯定都不陌生, 但可能并不是每个用过这两个方法的同学, 都了解其内部的实质

甚至可能会错误的把两个实现定时调用的函数理解成了类似thread一样的东西, 认为会在一个时间片内, 并发的执行调用的函数, 似乎很好很强大, 但其实并不是如此, 实际的情况是javascript都是以单线程的方式运行于浏览器的javascript引擎中的, setTimeout和setInterval的作用只是把你要执行的代码在你设定的一个时间点插入js引擎维护的一个代码队列中, 插入代码队列并不意味着你的代码就会立马执行的,理解这一点很重要. 而且setTimeout和setInterval还有点不一样. 

先谈谈setTimeout

 


  1. function click() { 
  2. // code block1... 
  3. setTimeout(function() { 
  4. // process ... 
  5. }, 200); 
  6. // code block2 
  7. }  

假设我们给一个button的 当我们按下按钮后, 肯定先执行block1的内容, 然后运行到setTimeout的地方, setTimeout会告诉浏览器说, "200ms后我会插一段要执行的代码给你的队列中", 浏览器当然答应了(注意插入代码并不意味着立马执行), setTimeout代码运行后, 紧跟其后的block2代码开始执行, 这里就开始说明问题了, 如果block2的代码执行时间超过200ms, 那结果会是如何? 或许按照你之前的理解, 会理所当然的认为200ms一到, 你的process代码会立马执行...事实是, 在block2执行过程中(执行了200ms后)process代码被插入代码队列, 但一直要等click方法执行结束, 才会执行process代码段, 从代码队列上看process代码是在click后面的, 再加上js以单线程方式执行, 所以应该不难理解. 如果是另一种情况, block2代码执行的时间<200ms, setTimeout在200ms后将process代码插入到代码队列, 而那时执行线程可能已经处于空闲状态了(idle), 那结果就是200ms后, process代码插入队列就立马执行了, 就让你感觉200ms后, 就执行了. 
再看看setInterval 
这里可能会存在两个问题: 
1.时间间隔或许会跳过 
2.时间间隔可能<定时调用的代码的执行时间

 


  1. function click() { 
  2. // code block1... 
  3. setInterval(function() { 
  4. // process ... 
  5. }, 200); 
  6. // code block2 
  7. }  

和上面一样我们假设通过一个click, 触发了setInterval以实现每隔一个时间段执行process代码

 


比如 block1代码执行完, 在5ms时执行setInterval, 以此为一个时间点, 在205ms时插入process代码, click代码顺利结束, process代码开始执行(相当于图中的timer code), 然而process代码也执行了一个比较长的时间, 超过了接下来一个插入时间点405ms, 这样代码队列后又插入了一份process代码, process继续执行着, 而且超过了605ms这个插入时间点, 下面问题来, 可能你还会认为代码队列后面又会继续插入一份process代码...真实的情况是,由于代码队列中已经有了一份未执行的process代码, 所以605ms这个插入时间点将会被"无情"的跳过, 因为js引擎只允许有一份未执行的process代码, 说到这里不知道您是不是会豁然开朗呢...

为了这种情况你可以用一种更好的代码形式

 


  1. setTimeout(function(){ 
  2. //processing 
  3. setTimeout(arguments.callee, interval); 
  4. }, interval);  

这个估计稍微想一下, 就明白其中的好处了, 这样就不会产生时间点被跳过的问题内容就到这里, 希望能有所帮助, 可能我表达的不是很清楚如果觉得自己英语基础不错可以直接看


里有关advanced Timers这节内容, 个人认为这本书真的很不错, 无论是想从零学起, 还是平日没事翻翻参考参考 都很不错, 作者是yahoo里很牛的一位前端开发工程师 : )


1.setTimeout(表达式,延时时间) 
在执行时,是在载入后延迟指定时间后,去执行一次表达式,记住,次数是一次 ,setTimeOut 延迟执行一次(只执行一次) 放控制函数内部

例子:setTimeout调用又返回值的函数

<html>
<head>
<title>setTimeout调用又返回值的函数</title>
<script language="javascript" type="text/javascript">
    var retValue = "";

    function test()
    {
        return "哈哈哈哈哈";
    }

    function clickButton1()
    {
        var iTimeoutId = setTimeout("retValue = test() ",1000);
    }
    
    function clickButton2()
    {
        alert(retValue);
    }
    
</script>
</head>
<body>
    <input type="button" value="button1">
    <input type="button" value="button2">
</body>
</html>
例子:用setTimeout实现的自动变化显示随机数的效果:

<html> 
<head> 
<script> 
window. 
function sett() 

document.body.innerHTML=Math.random(); 
setTimeout("sett()",500); 

</script> 
</head> 
<body> 
</body> 
</html>

2.setInterval(表达式,交互时间) 
则不一样,它从载入后,每隔指定的时间就执行一次表达式 ,setInterval 定时执行一次(循环执行) 放控制函数外部

例子:用setInterval实现的自动变化显示随机数的效果:

<html> 
<head> 
<script> 
function sett() 

document.body.innerHTML=Math.random(); 

setInterval("sett();", 500); 
</script> 
</script> 
</head> 
<body> 
</body> 
</html>
例子:
<html> 
<head> 
<script language="javascript"> 
function text(){ 
this.aa="aaaa"; 
this.aa="adfadf"; 
window.obj = this; 
this.showMsg=msg; 
function msg(){ 
alert(obj.aa); 
setTimeout("obj.showMsg()",1000); 


var text1=new text; 
text1.showMsg(text1); 
</script>

</head> 
<body> 
</body> 
</html>

 

 

停止: 
主要是利用 
window.clearInterval(intervalID); 
window.clearTimeout(timeoutID); 
<SCRIPT>   
  var   intervalID=0;   
  function   f_start(){   
  intervalID=window.setInterval("f_add()",500);   
  }   
  function   f_add(){   
  }   
  function   f_stop(){   
  window.clearInterval(intervalID);   
  }   
  </SCRIPT> 

 

 

 

 

*********************************

 上一篇写了关于setTimeout的东西,想再写点setInterval的, 并且这次写的严谨些。
    Java可发者熟悉对象的wait()方法,可使程序暂停,再继续执行下一行代码前,等待指定的时间量。 这种功能非常有用,遗憾的是,JavaScript 未提供相应的支持。 但这种功能并非完全不能实现,有几种方法可以采用。
    JavaScript支持暂停和时间间隔,这可有效地告诉浏览器应该何时执行某行代码。 所谓暂停,是在指定的毫秒数后执行的代码。 时间间隔是反复执行指定的代码,每次执行之间等待指定的毫秒数。
    可以用window对象的setTimeout()方法设置暂停。该方法接受两个参数,要执行的代码和在执行它之前要等待的毫秒数(1/1000秒)。第 一个参数可以是代码串(与eval()函数的参数相同),也可以是函数指针。例如,下面的代码都在1秒钟后显示一条警告:
    setTimeout("alert('Hello World!')",1000);
    setTimeout(function(){ alert('Hello World!'); },1000);
当然,还可以引用以前定义的函数:
    function sayHelloWorld()
    {
        alert("Hello World!");
    }

    setTimeout(sayHelloWorld,1000);
    调用setTimeout()时,它创建一个数字暂停ID,与操作系统中的进程ID相似。暂停ID本质上是要延迟的进程ID,再调用 setTimeout()后,就不应该再执行它的代码。要取消还未执行的暂停,可调用clearTimeout()方法,并将暂停ID传递给它:
    var iTimeoutId = setTimeout("alert('Hello World!')",1000);
    alert(iTimeoutId);
    clearTimeout(iTimeoutId);
其中,iTimeoutId 是一串数字,例如 38734218

 

    你也许会问:“为什么要定义暂停,又在执行它之前将其取消呢?”请考虑在大多数应用程序中可见的工具提示。当把鼠标移动到一个按钮上时,停留一会,等待出 现黄色的文本框,提示该按钮的功能。如果只是短暂的把鼠标该按钮上,然后很快将其移动到另一个按钮上,那么第一个按钮的工具提示就不会显示,这就是要在执 行暂停代码前取消它的原因。因为你在执行代码前只想等待指定的时间量。如果用户的操作产生了不同的结果,则要取消该暂停。
    时间间隔与暂停的运行方式相似,只是它无限此地每隔指定的时间段就重复执行一次指定的代码。可调用setInterval()方法设置时间间隔,它的参数与setTimeout()相同,是要执行的代码和每次执行之间等待的毫秒数。例如:
    setInterval("alert('Hello world!')",1000);
    setInterval(function() { alert("Hello world!"); },1000);

    function sayHelloWorld()
    {
        alert("Hello World!");
    }

    setInterval(sayHelloWorld,1000);
    此外,与setTimeout()类似,setInterval()方法也创建时间间隔ID,以标识要执行的代码。clearInterval()方法可 用这个ID阻止再次执行该代码。显然。这一点在使用时间间隔时更重要,因为如果不取消时间间隔,就会一直执行它,直到页面被卸载为止。下面是时间间隔用法 的一个常见示例:
    var iNum = 0;
    var iMax = 100;
    var iIntervalId = null;

    function incNum()
    {
        iNum++;

        if(iNum == iMax)
        {
            clearInterval(iIntervalId);
        }
    }

    iIntervalId = setInterval(incNum, 500);
    在这段代码中,每隔500毫秒就对数字iNum进行一次增量运算,直到它达到最大值(iMax), 此时该时间间隔将被清除。也可以用暂停实现该操作,这样即不必跟踪时间间隔的ID,代码如下:
    var iNum = 0;
    var iMax = 100;
    function incNum()
    {
        iNum++;
        if(iNum != iMax)
        {
            setTimeout(incNum,500);
        }
    }

    setTimeout(incNum,500);
    这段代码使用链接暂停,即setTimeout()执行的代码页调用了setTimeout()。如果在执行过增量运算后,iNum不等于 iMax,就调用setTimeout()方法。不必跟踪暂停ID,也不必清除它,因为代码执行后,将销毁暂停ID。





      本文转自许琴 51CTO博客,原文链接:http://blog.51cto.com/xuqin/949052,如需转载请自行联系原作者





版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
QT update和repaint的区别
void QWidget::repaint ( int x, int y, int w, int h, bool erase = TRUE ) [槽] 通过立即调用paintEvent()来直接重新绘制窗口部件,如果erase为真,Qt在paintEvent()调用之前擦除区域(x,y,w,h)。
1023 0
Hibernate中Session.load与Session.get的区别
Session.load/get方法均可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象。其区别在于: 如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个ObjectNotFoundException。
616 0
git revert和reset区别
1.在github上建立测试项目并克隆到本地 2.本地中新建两个文本文件   3.将a.txt commit并push到远程仓库  执行 git add a.txt, git commit -m "a.
728 0
BLOCKED,WAITING,TIMED_WAITING有什么区别?-用生活的例子解释
翻译原文地址: https://dzone.com/articles/difference-between-blocked-waiting-timed-waiting-e BLOCKED,WAITING和TIMED_WAITING是很重要的线程状态,但是经常对我们造成困扰。如果需要分析线程dump必须要对其有一定的理解。使用生活的例子,本文将每个状态变成了简单的例子。 与正式的Jav
2414 0
【高并发】ScheduledThreadPoolExecutor与Timer的区别和简单示例
JDK 1.5开始提供ScheduledThreadPoolExecutor类,ScheduledThreadPoolExecutor类继承ThreadPoolExecutor类重用线程池实现了任务的周期性调度功能。在JDK 1.5之前,实现任务的周期性调度主要使用的是Timer类和TimerTask类。本文,就简单介绍下ScheduledThreadPoolExecutor类与Timer类的区别,ScheduledThreadPoolExecutor类相比于Timer类来说,究竟有哪些优势,以及二者分别实现任务调度的简单示例。
123 0
linux中service *** start与直接运行/usr/bin/***的区别
在linux想要运行启动一个服务有两种方法: 1,运行/etc/init.d/目录下的shell脚本,还可以有快捷方式,service *** start/ stop/restart /status,  2,直接运行/usr/bin目录下的服务文件;   第一种方法启动的程序可以通过serv...
1025 0
21114
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载