汇总归纳setTimeout和setInterval的异同

692 阅读2分钟
  • 简单提一下用法

    setTimeout(fn,delay,[, args...] ) setInterval(fn,delay,[, args...] )

  • 相同点

  1. 均为宏任务,计时结束后,在js主线程排队等待执行。例如设置delay 延时为1000。那执行的延迟肯定会大于(取决于主线程是否有正在执行的)或等于1s

  2. 若主线程在它们前面执行的任务,发生了阻塞(例如死循环等)变不会执行回调。例如

    var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); // end 不会弹出

  • 不同点 
  1. setTimeout 为延时执行。setInterval为设定间隔时间循环执行

  2. setInterval每执行一次都会进入主线程的任务队列中‘排队’执行。若进入任务队列中存在‘同样的任务(即前面进入队列排队的任务还没有执行)’则当前任务会被忽略掉不进入任务队列等待执行。

  3. setInterval 如果参数中的fn 执行时间过长,则可能会出现没有时间间隔循环执行的效果。可以理解为(setInterval则总是在每10ms的时候尝试执行一次回调,它不管上一次回调是什么时候执行的。)

  • 代码实践示例:返回倒计时函数

    /**

    • 倒计时器
    • @param {Number} total 倒计时总数(秒)
    • @param {Function} callback 回调函数
    • @return {Function} stop 返回结束函数 */function countDown(total, callback) {
      var startTime = new Date().getTime();
      var count = 0
      let timer = null
      function fixed() { //这里做 时间修正 count++;
      var offset = new Date().getTime() - (startTime + count * 1000)
      var nextTime = 1000 - offset
      if (nextTime < 0) nextTime = 0
      timer = setTimeout(fixed, nextTime)
      callback(total--)
      }
      timer = setTimeout(fixed, 1000)
      return function () {
      clearTimeout(timer)
      } }
  • 总结:

  1. 无论是setTimeout还是setInterval,触发时,如果当前进程不为空,都得去排队等待执行,这一点上是无差异的。
  2. 区别是,setTimeout只需排一次队,setInterval则需要按照预设的间隔时间,每到时间点都去排一下。
  3. setInterval去排队时,如果发现自己还在队列中未执行,则会被drop掉。也就是说,同一个inerval,在队列里只会有一个。
  4. 因为队列机制,无论是setTimeout还是setInterval,第一次触发时的时间,只会等于大于预设时间,不可能小于。
  5. 对于setInterval来说,如果执行时间大于预设间隔时间,很可能导致连续执行,中间没有时间间隔,这是很糟糕的,很可能会耗费大量cpu.

引用:www.cnblogs.com/youxin/p/33…
www.cnblogs.com/crith/p/996…