debounce-throttle

2024/2/17

防抖节流都是利用 setTimeout 和闭包 来实现的。

防抖

  • 单位时间内,对于连续触发的事件,只执行最后一次.
  • 利用定时器,每次触发前清除掉之前的定时器 (重新开始)

防抖应用场景:

  1. 文本输入
  2. 编辑器的实时保存

节流

  • 单位时间内,对于连续触发的事件,只执行一次.
  • 利用定时器,等待定时器执行完毕,才开启定时器

节流应用场景:

  1. 快速点击,
  2. 鼠标滑动,
  3. scoll
  4. resize

如果希望实时变化,使用节流,如果希望在不变化了后在重新调用接口,就需要使用防抖,所以这需要看具体的使用场景。

  1. 下拉加载
  2. 视频播放的时间记录

其实分为立即执行和非立即执行,只不过由于 delay 的值一般设置的都会很小,一般感知不到,所以普遍用的都是非立即执行版本 (通过定时器去延缓执行函数). 而立即执行函数是借助定时器延缓的 timerId, 而不是函数了。

function debounce(fn: Function, delay: number) {
    let timerId: ReturnType<typeof setTimeout>;

    return function(...args: any[]) {
        clearTimeout(timer); // 对于不判断定时器是否存在,直接进行 clear
        timerId = setTimeout(() => {
        fn(...args)
        }, delay)
    }
}

function throttle(fn: Function, delay: number) {
    let timerId: ReturnType<typeof setTimeout>;

    return function (...args, any[], delay) {
        // 如果定时器不存在,再运行函数
        if(!timerId) {
            timerId = setTimeout(() => {
            fn(...args)
            // 函数结束后,置空定时器
            timerId = null;
            }, dealy)
        }
        }
    }