鍍金池/ 問答/網(wǎng)絡(luò)安全  HTML/ 阿里前端面試題:requestAnimationFrame實現(xiàn)類似setInte

阿里前端面試題:requestAnimationFrame實現(xiàn)類似setInterval的計時器

使用requestAnimationFrame實現(xiàn)類似setInterval的計時器

回答
編輯回答
浪婳

供參考,沒有實現(xiàn)字符串功能,反正也不推薦使用。

function setInterval2 (cb, delay, ...args) {
  // 記錄所有正在運行的 interval 用于撤銷
  let pool = window[Symbol.for('IntervalPool')]
  if (!pool) {
    pool = {}
    window[Symbol.for('IntervalPool')] = pool
  }

  // interval 最低 10ms,雖然每 frame 至少得 16ms
  delay = delay >= 10 ? delay : 10
  // interval id
  let ticket = Date.now()
  // 每次 interval 開始時間
  let startTime = ticket
  pool[ticket] = true
  loop()
  return ticket

  function loop () {
    if (!pool[ticket]) { return }
    const now = Date.now()
    if (now - startTime >= delay) {
      startTime = now
      cb(...args)
    }
    requestAnimationFrame(loop)
  }
}

function clearInterval2 (ticket) {
  let pool = window[Symbol.for('IntervalPool')]
  if (pool && pool[ticket]) {
    delete pool[ticket]
  }
}
2017年1月23日 09:34
編輯回答
挽青絲
function a(callback){
       requestAnimationFrame(function(){
           //你的代碼
           callback && callback()
           a()
       })
}

需要注意requestAnimationFrame的瀏覽器兼容性問題

window.requestAnimationFrame = window.requestAnimationFrame || 
window.webkitRequestAnimationFrame || 
window.mozRequestAnimationFrame || 
window.msRequestAnimationFrame || 
window.oRequestAnimationFrame || 
function (callback) {
    //為了使setTimteout的盡可能的接近每秒60幀的效果
    window.setTimeout(callback, 1000 / 60);
};
    
window.cancelAnimationFrame = window.cancelAnimationFrame || 
Window.webkitCancelAnimationFrame || 
window.mozCancelAnimationFrame || 
window.msCancelAnimationFrame || 
window.oCancelAnimationFrame || 
function (id) {
    //為了使setTimteout的盡可能的接近每秒60幀的效果
    window.clearTimeout(id);
}
2017年5月20日 21:40