• 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)
    
    • 1
    • 2
    • 3
    • 4

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

    用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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    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在每次屏幕刷新的时候被调用

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

    练习题

    for(var i = 0; i < 6; i++) {
        setTimeout(() => {
            console.log(i)
        }1000)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    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)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    async function fn (){
        for(let i=0;i<6;i++){
            let res = await fn1(i);
            console.log(res);
        }
    }
    
    function fn1(item){
      return new Promise((resolve,reject)=>{
        setTimeout(()=>{
          resolve(item)
        },1000)})
    }
    fn();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    Apache OFBiz 路径遍历导致RCE漏洞复现(CVE-2024-36104)
    Ribbon简单使用
    三款“非主流”日志查询分析产品初探
    Oracle的学习心得和知识总结(八)|Oracle数据库PL/SQL语言GOTO语句技术详解
    vue3 + fastapi 实现选择目录所有文件自定义上传到服务器
    C++小型公司人员信息管理系统
    Linux——简单指令汇总
    深入学习JVM(Java虚拟机)
    形象谈JVM-第二章-认识编译器
    this的四个绑定规则
  • 原文地址:https://blog.csdn.net/qq_41370833/article/details/126128137