前端组知识库

👍欢迎大家积极投稿交流👍

如果文档内容陈旧或者链接失效,请发现后及时同步,我将尽快修改

👇微信👇

图片
Skip to content

定时器

setTimeout

setTimeout(fn,delay,params) 指定函数在指定delayms之后执行一次

setInterval

setInterval(fn,delay,params) 指定函数每隔delayms执行一次

因为js是单线程,如果前面的代码影响了性能,就会导致 setTimeout/setInterval等不会按期执行

requestAnimationFrame

由系统决定回调函数的执行时机,每次刷新的间隔中会执行一次回调函数,不会引起丢帧,不会卡顿

通常为60Hz的刷新率,即16.6ms执行一次

requestAnimationFrame 自带函数节流功能,基本可以保证在 16.6 毫秒内只执行一次(不掉帧的情况下)

差异

  • 使用setTimeout/setInterval,当页面被隐藏或最小化时,仍然在后台执行任务
  • requestAnimationFrame则完全不同,当页面处理未激活的状态下,该页面的屏幕刷新任务也会被系统暂停

下面介绍使用requestAnimationFrame实现定时器的方式

mySetTimeout

js
function mySetTimout(callback, delay) {
  let timer,
    start = Date.now()
  const loop = () => {
    if (start + delay > Date.now()) {
      timer = requestAnimationFrame(loop)
    } else {
      callback(timer)
    }
  }
  timer = requestAnimationFrame(loop)
  return timer
}

使用

js
mySetTimout((timer) => {
  console.log('over' + timer)
}, 1500)

mySetInterVal

js
function mySetInterval(callback, delay) {
  let timer,
    start = Date.now()
  const loop = () => {
    timer = requestAnimationFrame(loop)
    if (start + delay <= Date.now()) {
      callback(timer)
      start = Date.now()
    }
  }
  timer = requestAnimationFrame(loop)
  return timer
}

使用

js
let a = 1
mySetInterval((timer) => {
  a++
  console.log(a, timer)
  if (a === 3) {
    cancelAnimationFrame(timer)
  }
}, 1000)

上次更新于: