setTimeout

setTimeout(fn, [delay], [arg]),遇到正在执行的代码阻塞,可能会超时执行

  • 用setInterval实现setTimeout
mySetTimeout(() => {
    console.log('mySetTimeout')
}, 1000)

function mySetTimeout(callback, ms) {
    var timer = setInterval(() => {
        callback()
        clearInterval(timer)
    }, ms)
}

setInterval

mySetInterval(() => console.log('mySetInterval'), 1000)

function mySetInterval(callback, ms) {
    var timer = setTimeout(() => {
        callback();
        clearTimeout(timer)
        mySetInterval(callback, ms)
    }, ms)
}
  • 用setTimeout实现setInterval
var timer = myInterval(() => {
    console.log('myInterval')
}, 1000)

function myInterval(callback, ms) {
    let timer = null
    function fn() {
        callback()
        let intervalId = timer
        // 重复调用
        timer = setTimeout(fn, ms)
        // 清空上一次的定时器
        clearTimeout(intervalId)
        return intervalId
    }
    return setTimeout(fn, ms)
}

function clearMyInterval(intervalId) {
    clearTimeout(intervalId)
}

为什么要用setTimeout 替代setInterval

  • setInterval 会无视错误代码,即使代码报错,也会一直执行下去
  • setInterval 会无视网络延迟,比如1s更新一次数据的需求,假如服务器请求数据发生延迟等情况,setInterval 不会等数据请求完才会执行下一次请求,而是时间到了就会再次请求,很容易造成请求堵塞,或者渲染堵塞,严重的会之间卡死
  • setInterval 会出现越跑越快的问题

requestAnimationFrame

一个专门的循环函数,旨在浏览器中高效的运行动画,在浏览器重新加载显示内容之前执行指定的代码块,从而允许动画以适当的帧速率运行,而不管它在什么环境中运行,可运行多次。解决setInterval会丢帧的问题

requestAnimationFrame与setTimeout相比

  • requestAnimationFrame最大的优势是由浏览器决定回调函数的执行时机,即紧跟浏览器的刷新步调
  • 其次,CPU节能:setTimeout实现的动画,当页面被隐藏或最小化时,setTimeout仍然在后台执行动画任务(只不过执行时间有所延迟),但其实此时页面不可见,刷新动画没有意义,而且还浪费CPU资源和电池寿命。而requestAnimationFrame不同,当页面处于未激活状态时,页面的屏幕绘制任务会被浏览器暂停,requestAnimationFrame停止渲染,当页面再次激活时,动画会从上次停留的地方继续执行,有效节省了CPU开销,提升性能和电池寿命。
  • 也解决了setInterval会丢帧的问题
// 不指定时间间隔,在当前条件下尽可能快速平稳的运行它
var raf = requestAnimationFrame()

// 取消
cancelAnimationFrame(raf)

results matching ""

    No results matching ""