防抖和节流

74 阅读2分钟

1.函数防抖

  1. 一个频繁触发的函数,在规定的时间内重复执行函数,那么只让最后一次函数执行生效,之前的函数执行的都不生效,并且会重新触发定时器计时

  2. 使用的是定时器 delay=2s 第一次点击,清除上次的定时器,隔2秒时间触发定时器,那么2秒内再点一次再次清除上一次你点的2s内的定时器 接着再隔2秒时间触发定时器 .... 一直点一直循环直到最后一次才生效

  3. 参考:

juejin.cn/post/684490… juejin.cn/post/696871…
juejin.cn/post/703132…

4.代码

    // 防抖
    function dobounce(fn, delay) {
      let timer = null;   // 这个外层函数只会触发一次,用来存值 闭包 
      return function () {  // 返回一个新函数
        let args = arguments; // 获取参数
        // 清除上一个定时器
        if (timer) {
          clearTimeout(timer)
        }
        // 开启定时器,执行延迟多少秒后执行的高频触发函数 
        // 为了封装的严谨性,修正this指向为调用dobounce所指的对象  并传参(若有)
        timer = setTimeout(() => {
          fn.apply(this, args)
        }, delay)
      }
    }
    
    
    -----------------------------------
    // 测试
    function task(a, b) {
      console.log("我被点击了,数据是:", a, b);
    }

    let newTask = dobounce(task, 1000)   // 返回的是一个函数体 让newTask代替task执行
    // newTask(10,20,30)
    
    let handleClick = () => {
      newTask(10, 20)
    }

2.函数节流

一个频繁触发的函数,在规定在一个单位时间内,只能触发一次函数,之后的函数执行都不生效如果这个单位时间内触发多次函数,只有第一次函数执行有效

    // 节流
    function throttle(fn, delay) {
      let start = 0   // 定义初始时间 这个外层函数只会触发一次,用来存值 闭包 
      return function () {
        let args = arguments
        let now = Date.now()  // 返回自 1970 年 1 月 1 日 00:00:00 (UTC) 到当前时间的毫秒数 
        // console.log(now,start,now - start,delay);
        if(now - start > delay){  // 当前时间 - 开始时间 大于 延迟时间 那么就执行函数
          start = now           // 将上次的时间改为当前时间
          fn.apply(this,args)   // 执行函数
        }
      }
    }

    ---------------------------------

    // 测试
    function task1(a, b) {
      console.log("我被点击了,数据是:", a, b);
    }

    let newTask1 = throttle(task1, 2000)   // 返回的是一个函数体
    // newTask1(10,20,30)

    let handleClick1 = () => {
      newTask1(10, 20, 30)
    }

3.总结:

  • 函数防抖和函数节流都是防止某一时间频繁触发,但是这两兄弟之间的原理却不一样。
  • 函数防抖是某一段时间内只执行一次,而函数节流是间隔时间执行。

3.1 结合应用场景

debounce:

  1. search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
  2. window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次

throttle:

  1. 鼠标不断点击触发,mousedown(单位时间内只触发一次)
  2. 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断