setTimeout()与setInterval()

js引擎是单线程引擎,一段时间只能执行一个事件,为了控制要执行的代码,js拥有任务队列。队列中任务按照一定的顺序排列,而这些任务按照排列的顺序执行。

当函数foo1()箱与函数foo2()调用时一般先执行foo1()再执行foo2(),事件执行顺序与程序排列顺序相同叫“同步模式””

但是“同步模式”有时会出现缺点,如:

假设某函数foo()非常耗时,那么在执行foo()时用户可能误以为浏览器没响应,这时就应该让耗时较长的事件后执行避免浏览器无响应。

当事件执行顺序与程序排列顺序不同时,为“异步模式“”

利用setTimeout就完成异步,下面介绍setTimeout

setTimout()接受两个参数,第一个参数可以是字符串,也可以是函数,为指定的要执行的代码。

第二个参数是时间,单位毫秒,表示等待时间,它告诉js再过多长时间把当前任务添加到队列中,因此经过改时间后指定的代码未必执行。

当使用setTimOut时,当前任务会被添加到队列尾部,因此,当队列为空的时添加的代码会立即执行,当队列不为空时,要等待前面的代码执行完成以后再执行

for( var i = 1;  i<=10; ++i){

setTimeout(  function(){

console.log(i)},0)

}


这里输出10个11,这里输出10个值是因为循环了10次通过setTimeout( )将10个console.log(i)放在了队尾(上面说的,setTimeout会等待指定的时间后将添加的代码添加到队尾)

,但为什么会输出10个相同的值呢,为什么不是输出1,2,3,4,5,。。。10呢。这是因为虽然循环中的函数是在各个迭代中分别定义的,但是它们都是在一个共享的全局作用域上,因此实际上只有一个i。所以最后输出的i值是相同的,当循环结束时i为11,因此输出的都为11.

上面的10 11上面还有个数值46,这是调用setTimeout()后从返回的唯一数值ID

我们也可以建立新的作用域使得输出是1,2.。。10,如下

for( var i=1; i<=10; ++i ){
    (function(){
        var j = i
        setTimeout( function(){console.log(j)},0 )
    })()
}

以上代码可参考 《你不知道的js上册》


下面介绍setInterval(), setInterval()拥有两个参数,一个是字符串或函数,另一个是时间,表示每隔指定的时间调用一次指定的代码,

setInterval()也会返回一个唯一的数值ID,setTimeut和setInterval()都可以利用唯一数值ID取消还没执行的调用

setInterval()的间歇调用会一直执行,直到页面被卸载或者被取消


var num=0

function foo(){

num++

if( num==10 ){

clearInterval( intervalId )

console.log("结束了"+intervalId)

}

}

intervalId = setInterval(  foo, 1000 )


这个函数在游戏里可以用到,因为游戏就是一帧一帧的图像,每隔 n 毫秒更新一次图像就成了游戏,动画。。。

上面的模式在也可以用setTimeout()来实现


var num = 0

function foo(){

num++

if( num<10 ){

 setTimeout( foo,1000 )

}

else{

console.log("结束了")

}

}

foo()


js高级教程里说,后一个间歇调用可能在前一个间歇调用结束之前启动。我对这句话还不是很理解,但我觉得启动不是执行,js不可能同时执行两个任务因为js引擎是单线程的。js高后面高级定时器对这个有说明,马上看。顺便说下,定时器不是线程!!!

参考:http://www.ruanyifeng.com/blog/2012/12/asynchronous_javascript.html

js高级教程

你不知道的js上册



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值