东北话版 - JS 节流与防抖解析与实践

167 阅读1分钟

 一、防抖

使用场景: 比如一些按钮,它的功能就是保存数据,如果不增加按钮点击后的loading,可能就会出现连续点击,误操作等情况,触发多次,那么就可以使用” 防抖 “来解决问题。

防抖概念: 解决多次触发,常用方式为使用定时器来控制触发的时机,当第一次触发按钮时会创建一个定时器,执行规定的时间,当时间流逝完成后,就触发对应要操作的函数,当时间未流逝完成时再次触发按钮会清空上一次的定时器,然后重新创建定时器,执行规定时间,以此类推,直到最后一次规定时间执行完成。

🍩例子:

// 防抖函数
const useAntiShake = (fn: { (): void; (): any }, timeout: number) => {
  let time: NodeJS.Timeout | null = null
  return () => {
    if (time) {
      clearTimeout(time)
    }
    time = setTimeout(() => {
      fn && fn()
    }, timeout)
  }
}
export default useAntiShake

// 使用防抖
import React, { useState } from "react"
import useAntiShake from "./useAntiShake"
const Index = () => {
  const handleClick = () => {
    console.log('6666')
  }
  return <div>
    <button onClick={ useAntiShake(handleClick, 1000) }>点击我</button>
  </div>
}
export default Index

防抖结果: 在规定时间内频繁点击按钮,只会执行一次 !

二、节流

使用场景:  节流顾名思义,节省流量防止频繁触发某事件, 比如在捕捉window窗口大小改变,捕捉window滚动条事件时,所对应的函数触发频率相当的大,每秒很多次,这样大大影响我们的性能,出现了很多不必要的开销, 那么这时我们就可以使用 "节流" 来控制它的触发频率。

节流概念: 当事件频繁触发时,我们需要控制它触发时间间隔,可使用定时器去处理节流,当函数第一次触发的时候,开启一个定时器并在全局存储该定时器,在规定的时间流逝后执行此函数并清除该定时器,如果在规定时间内又执行了一次,不予处理,只有定时器不存在的时候才会再次创建定时器,执行下一次函数

// 节流函数
const useThrottle = (fn: { (): void; (): any }, timeout: number) => {
  let time: NodeJS.Timeout | null = null
  return () => {
    if (!time) {
      time = setTimeout(() => {
        fn && fn()
        time = null
      }, timeout)
    }
  }
}
export default useThrottle

// 使用节流函数
import React, { useState } from "react"
import useThrottle from "./useThrottle"
const Index = () => {
  const handleResize = () => {
    console.log('6666')
  }
  window.addEventListener('resize', useThrottle(handleResize, 3000))
  return <div>节流</div>
}
export default Index

节流结果:  频繁触发函数,会根据规定时间

三、总结: 防抖和节流是我们日常代码操作中常见的优化点,避免出现频繁触发或多次触发的情况, 它的原理就是通过 "闭包" 实现变量一直被引用,从而不会被垃圾回收机制所回收,这样就可以持续的操作同一个变量,而这个变量就充当开关的作用,实现节流和防抖。