系统理解 setTimeout()和 setInterval()

2018-11-08  本文已影响0人  msqt

今天刚好在看setTimeout()的一个案例,在案例的解析中提到了setTimeout()和setInterval()的使用区别,但是比较理论,所以

决定自己也总结一下,写写例子帮助理解一下。

       首先是说说这两个方法的具体时如何使用的。

1、setTimeout()方法

      这个方法所有浏览器都支持,setTimeout( ) 是属于 window 的 method, 但我们都是略去 window 这顶层物件名称, 这是用来

设定一个时间, 时间到了, 就会执行一个指定的 method。

      定义和用法: setTimeout()方法用于在指定的毫秒数后调用函数或计算表达式。

      语法: setTimeout(code,millisec)

      参数: code (必需):要调用的函数后要执行的 JavaScript 代码串。millisec(必需):在执行代码前需等待的毫秒数。   

 提示: setTimeout() 只执行 code 一次。如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout()(即利用递归)。

      看完了基本的语法,接下来我写一个很简单的例子说明这个的使用方法。

代码如下:

<!DOCTYPE html>

setTimeout()使用

请等待三秒!

setTimeout("alert('终于等到你了!')",3000)

      当我们打开网页3秒时,就会弹出一个框。但是,只会弹出一次,因为 setTimeout()不会自动重复执行,是在载入后的延迟指定

时间去执行一次表达式。

当然,我们也可以让setTimeout()执行函数,而且可以重复执行多次(利用递归),而不是一次。

代码如下:

<!DOCTYPE html>

varx =0;

functioncountSecond()

        {

x = x+1;

document.haorooms.haoroomsinput.value = x;

setTimeout("countSecond()",1000)

        }

    countSecond();

       实现的方法就是让函数自身反复调用。

2、setInterval()方法

setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。setInterval() 方法会不停地调用函数,直到 

clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。

语法: setInterval(code,millisec[,"lang"])

     参数: code 必需。要调用的函数或要执行的代码串。millisec 必须。周期性执行或调用 code 之间的时间间隔,以毫秒计。

返回值: 一个可以传递给 Window.clearInterval() 从而取消对 code 的周期性执行的值。

     如果我们想要每隔3秒就弹出一个框要如何实现呢?

代码如下:

<!DOCTYPE html>

Title

functiontest(){

this.name ="setInternal";

this.waitMes =function(){

varthat =this;

setInterval(function(){

                alert(that.name);

},3000);

        }

    }

varte =newtest();

    te.waitMes();

       setInterval() 从载入后,每隔指定的时间就执行一次表达式。

3、区别

     通过上面可以看出,setTimeout和setinterval的最主要区别是:

    1)setTimeout只运行一次,也就是说设定的时间到后就触发运行指定代码,运行完后即结束。如果运行的代码中再次运行同样

的setTimeout命令,则可循环运行。(即 要循环运行,需函数自身再次调用 setTimeout());而 setinterval是循环运行的,即每

到设定时间间隔就触发指定代码。这是真正的定时器。

    2)setinterval使用简单,而setTimeout则比较灵活,可以随时退出循环,而且可以设置为按不固定的时间间隔来运行,比如第

一次1秒,第二次2秒,第三次3秒。

值得注意的是:

setTimeout(function(){

    console.log(1);

});

console.log(0);

这里,实际上,把setTimeout的第二个参数设置为0s,并不是立即执行函数的意思,只是把函数放入异步队列。浏览器先执行完同步队列里的任务,才会去执行异步队列中的任务。

setInterval()原理与setTimeout(),也是讲代码放入异步队列中。但是,setInterval()存在一个问题,

使用setInterval()的问题在于,定时器代码可能在代码再次被添加到队列之前还没有完成执行,结果导致定时器代码连续运行好几次,而之间没有任何停顿。而javascript引擎对这个问题的解决是:当使用setInterval()时,仅当没有该定时器的任何其他代码实例时,才将定时器代码添加到队列中。这确保了定时器代码加入到队列中的最小时间间隔为指定间隔。

  但是,这样会导致两个问题:1、某些间隔被跳过;2、多个定时器的代码执行之间的间隔可能比预期的小。

两者的工作原理:大家都知道,JavaScript是单线程执行的,setTimeout和setInterval执行原理其实也很简单。

setTimeout会在调用后的millisec时间间隔后往事件队列里添加回调函数,然后等待执行。 

setInterval会按照第二个参数的周期时间周期性的往事件队列添加回调函数,然后等待执行,这里的一个注意点是如果事件队列里的回调函数还没有执行,不会重复添加。

注:html5规定setTimeout和setInterval的延迟时间最少为4ms. 所以setTimeout(function(){},0)其实是setTimeout(function(){}, 4)。

如果上面代码中的onclick事件处理程序执行了300ms,那么定时器的代码至少要在定时器设置之后的300ms后才会被执行。队列中所有的代码都要等到javascript进程空闲之后才能执行,而不管它们是如何添加到队列中的。如下图:

 如图所示,尽管在255ms处添加了定时器代码,但这时候还不能执行,因为onclick事件处理程序仍在运行。定时器代码最早能执行的时机是在300ms处,即onclick事件处理程序结束之后。

实际上,把setTimeout的第二个参数设置为0s,并不是立即执行函数的意思,只是把函数放入异步队列。浏览器先执行完同步队列里的任务,才会去执行异步队列中的任务。

验证例子:

例一:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>菜鸟教程(runoob.com)</title>

<script>

(function(){

var i=0;

    setTimeout(function(){

        document.getElementById("demo").innerHTML=1233131123;

},2500)

setInterval(function(){

i++;

document.getElementById("demo").innerHTML=i;

},1000)

})()

</script>

</head>

<body>

<h1>我的第一个 JavaScript 程序</h1>

<p id="demo">这是一个段落</p>

<button type="button" onclick="displayDate()">显示日期</button>

</body>

</html>

此代码结果显示先后顺序:

1(1s)、2(2s)、1233131123(2.5s)、3(3s)、4(4s)........

原理分析:

例二:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>菜鸟教程(runoob.com)</title>

<script>

(function(){

var i=0;

setInterval(function(){

i++;

document.getElementById("demo").innerHTML=i;

setTimeout(function(){

        document.getElementById("demo").innerHTML=1233131123;

},2500)

},1000)

})()

</script>

</head>

<body>

<h1>我的第一个 JavaScript 程序</h1>

<p id="demo">这是一个段落</p>

<button type="button" onclick="displayDate()">显示日期</button>

</body>

</html>

效果及分析:

上一篇下一篇

猜你喜欢

热点阅读