setTimeout 、setInterval、requestAnimationFrame

setTimeout 、setInterval、requestAnimationFrame

面试题

  • setTimeout(cb, 0)会立刻执行吗?
  • settimeout定时的时间准确吗? 为什么不准确? 怎么解决?
  • setTimeout和requestAnimation的区别
  • requestAnimationFrame讲一下你的理解
  • setTimeout实际延迟时间
  • 用setTimeout实现setInterval,实现一个随时停止的版本
  • setTimeout 和 setInterval区别
  • JS实现动画的方式
  • requestAnimationFrame与requestIdleCallback分别是什么?
  • requestAnimationFrame的执行时机?
  • 事件循环,宏任务微任务
  • requestAnimationframe回调函数中进行大量计算,会阻塞页面的渲染吗

setTimeout定时器的时间准吗?

setTimeout的时间是指ms之后将回调函数放入宏队列中,当时间为0时,

  • 在nodejs中 setTimeout(demo, 0) === setTimeout(demo, 1),最小是1ms
  • 在浏览器里面 setTimeout(demo, 0) === setTimeout(demo, 4),最小是4ms
    在事件循环中,先执行完同步代码后,先需要执行微队列中任务,然后再到宏队列,所以定时器的事件是不准确的

setTimeout 和 setInterval

setTimeout(fn,time):在指定时间后执行一次回调函数
setInterval(fn,time):周期性地执行回调函数

setInterval存在的问题
1.某些间隔被跳过;
2.实际代码执行间隔 <= 设定的时间间隔

假设,某个onclick事件处理程序使用setInterval()设置了200ms间隔的定时器。如果事件处理程序花了300ms多一点时间完成,同时定时器代码也花了差不多的时间,就会同时出现跳过某间隔的情况
在这里插入图片描述使用setTimeout构造轮询能保证每次轮询的间隔

  setTimeout(function fn() {
    // do something
    setTimeout(fn, delay)
  }, delay)

当一个定时器执行完毕后,才开启另一个定时器。
这样做的好处 ①在前一个定时器代码执行完之前,不会向队列插入新的定时器代码,确保不会有任何缺失的间隔。② 它可以保证在下一次定时器代码执行之前,至少要等待指定的间隔,避免了连续的运行。

用setTimeout实现setInterval,可以随时停止
function mySetTimeout(fn,delay){
  let timer = null;
  let interval = ()=>{
    fn();
    timer = setTimeout(interval,delay); //开启后续定时器,取消也是取消后续的
  }
  setTimeout(interval,delay); //第一次调用定时器
  return {
    cancel:()=>{
      clearTimeout(timer);
    }
  }
}

const { cancel } = mySetTimeout(() => console.log(888),1000)
setTimeout(()=>{
  cancel()
},4000)

requestAnimationFrame H5新增API

JS实现动画的方法

  • setTimeout
  • setInterval
  • requestAnimationFrame

显示器的刷新频率是60Hz,浏览器也会尽量保持60Hz的刷新率运行,也就是16.7ms刷新一帧所以(60次/s)

requestAnimationFrame是什么?
requestAnimationFrame是H5新增的API类似于setTimeout ,告诉浏览器在重新渲染屏幕之前执行。主要用途是按帧对网页进行重绘

requestAnimationFrame的基本思想就是与显示屏的刷新频率保持同步,利用这个刷新频率进行页面重绘

setTimeout 和requestAnimationFrame 的区别

类型回调函数执行的时机是否在后台一直执行丢帧现象
setTimeout用户指定时间,放入宏队列中,最终执行的时间是不确定的
由于执行时间的不确定性,setTimeout的执行步调可能和屏幕的刷新步调不一致,从而引起丢帧现象。
requestAnimationFrame由系统决定回调函数的执行时机,在下次重绘之前调用×
它会在页面出现的时候才会执行,一旦页面不处于浏览器的当前标签,就会自动停止刷新
原因:当页面处于未激活的状态下,该页面的屏幕刷新任务会被系统暂停
×
在重绘之前调用不会丢帧

requestIdleCallback

浏览器一帧内需要完成如下六个步骤的任务

  • 处理用户的交互
  • JS 解析执行
  • 帧开始。窗口尺寸变更,页面滚去等的处理
  • requestAnimationFrame(rAF)
  • 布局
  • 绘制

与requestAnimationFrame的区别

  • requestAnimationFrame在每次屏幕刷新的时候被调用,重新渲染屏幕之前
  • requestIdleCallback在每次屏幕刷新时,判断当前帧是否还有多余的时间(上述6个步骤执行完后也就是重新渲染屏幕之后),如果有,则会调用requestIdleCallback的回调函数,

每隔1s输出

for(var i = 0; i < 6; i++) {
    setTimeout(() => {
        console.log(i)
    }1000)
}
  1. 上述代码会输出什么
    1s后同时输出6个6
  2. 如何优化让 0 - 1 - 2 - 3 - 4 - 5 每隔一秒输出一个
    输出012345可以将var改成let

每隔1s输出
实现1:增加输出间隔

for(let i = 0; i < 6; i++) {
  setTimeout(() => {
        console.log(i);
        timer = null;
    },1000*i)
}

实现2 利用await/async 等上一个定时器执行完毕后再执行下一个

async function fn (){
    for(let i=0;i<6;i++){
    	//await会阻塞程序
        let res = await fn1(i);
        console.log(res);
    }
}

function fn1(item){
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      resolve(item)
    },1000)})
}
fn();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值