setInterval

setTimeout和setInterval:

  1. 指定延迟后调用函数,
  2. 以指定周期调用函数

让我们想象一个意外情况,比如说下面的setInterval

setInterval(function () {
    func(i++);
}, 100)

我们每100毫秒调用一次func函数,如果func的执行时间少于100毫秒的话,在遇到下一个100毫秒前就能够执行完:

1;

但如果func的执行时间大于100毫秒,该触发下一个func函数时之前的还没有执行完怎么办?答案如下图所示,那么第二个func会在队列(这里的队列是指event loop)中等待,直到第一个函数执行完

3;

如果第一个函数的执行时间特别长,在执行的过程中本应触发了许多个func怎么办,那么所有这些应该触发的函数都会进入队列吗?

不,只要发现队列中有一个被执行的函数存在,那么其他的统统忽略。如下图,在第300毫秒和400毫秒处的回调都被抛弃,一旦第一个函数执行完后,接着执行队列中的第二个,即使这个函数已经“过时”很久了。

4;

还有一点,虽然你在setInterval的里指定的周期是100毫秒,但它并不能保证两个函数之间调用的间隔一定是一百毫秒。在上面的情况中,如果队列中的第二个函数时在第450毫秒处结束的话,在第500毫秒时,它会继续执行下一轮func,也就是说这之间的间隔只有50毫秒,而非周期100毫秒

那如果我想保证每次执行的间隔应该怎么办?用setTimeout,比如下面的代码:

  var i = 1
  var timer = setTimeout(function() { 
    alert(i++) 
    timer = setTimeout(arguments.callee, 2000)
  }, 2000)

上面的函数每2秒钟递归调用自己一次,你可以在某一次alert的时候等待任意长的时间(不按“确定”按钮),接下来无论你什么时候点击“确定”, 下一次执行一定离这次确定相差2秒钟的

setTimeout(function repeatMe() {     
  /* Some long block of code... */   
  setTimeout(repeatMe, 10);          
}, 10);

setInterval(function() {             
  /* Some long block of code... */   
}, 10);  

比如说:在处理DOM点击事件的时候通常会产生冒泡,正常情况下首先触发的是子元素的handler,再触发父元素的handler,如果我想让父元素的handler先于子元素的handler执行应该怎么办?那就用setTimeout延迟子元素handler若干个毫秒执行吧。问题是这个“若干个”毫秒应该是多少?可以是0

你可能会疑惑如果是0的话那不是立即执行了吗?不,看下面一道题目

(function () {
    setTimeout(function () {
        alert(2);
    }, 0);

    alert(1);
})() 

先弹出的应该是1,而不是你以为“立即执行”的2。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值