防抖和节流

防抖和节流

节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
防抖: n 秒后再执行该事件,若在 n 秒内被重复触发,则重新计时

目的都是,降低回调执行频率。节省计算资源

防抖

类似于 回城
按B回城,回城中再按B,重新回城
只执行最后一次

先来看个例子:

假设input是一个搜索框,每次输入完都会控制台输出 输入的内容。

结果:

如图,这里仅仅输入了一个 “前” 就触发了这么多次,那如果是每次输入完,进行一次搜索岂不是非常浪费资源


插入防抖

思路:
封装了一个函数debounce,fn -> 执行的函数,delay -> 间隔时间,通过return内部函数形成闭包,使 t 不会被清除。
第一次触发事件 t保存定时器唯一标识 ,开启定时器(开始计时),只有经过delay指定时间才会执行定时器里的代码。
除了第一次触发之后每次触发都会清除上一次的定时器
如果下一次触发与上一次触发间隔时间小于delay,就代表上一次的setTimeout还没有执行,就被清除了。
然后再开启一个新的定时器开始计时,经过delay指定时间 就执行定时器里的代码。

注意:定时器要用箭头函数拿到this,然后用指定this调用fn,这样fn的this才是指向inp的

结果:


节流

类似于 技能CD
按Q释放Q技能,然后Q技能进入CD,CD没好不能再次释放Q技能,如果CD好了就可以再次释放
控制执行次数

例子:

给全局对象window绑定一个滚动事件,滚动一次控制台输出'Hello World'

结果:

可以看到仅仅滚动了一点,这个事件就触发了40次,那如果是要滚动一次向服务器发送一次请求的话,那岂不是发送了40次?


插入节流

这里将结果一并放到图中

思路:
与防抖(debounce)同样的两个形参,fn -> 执行的函数,delay -> 间隔时间,通过return内部函数形成闭包,使 flag 不会被清除
第一次调用:flag默认值为true,判断flag ,开启定时器(开始计时),然后让 flag = false。
每次调用都会判断 flag 并让 flag = false
下一次触发如果与上次一触发间隔小于delay(指定时间),那就代表上一次的setTimeout还没有执行,只有setTimeout执行了 flag 才为 true。
这时 flag 依然为 false,所以不会开启定时器。
连续触发情况下,必须等待上一个定时器执行后 flag为true,下一次触发才会开启定时器

注意:这里的定时器也要用箭头函数拿到this。

结果:
如图,明显减少了触发的次数


总结

防抖:用户触发事件过于频繁,只要最后一次触发生效
节流:用户触发事件过于频繁,控制事件执行次数

由于上面都是图片,这里将两个函数放到下面方便自取:
// 防抖
function debounce(fn, delay){
  let t = null
  return function(){
    if(t !== null){
      clearTimeout(t)
    }
    t = setTimeout(() => {
       fn.call(this)
    },delay)
  }
}
// 节流
function throttle(fn, delay){
  let flag = true
  return function(){
    if(flag){
      setTimeout(() => {
        fn.call(this)
      },delay)
    }
    flag = false
  }
}
posted @ 2022-07-23 17:01  ycccc丶  阅读(29)  评论(1编辑  收藏  举报
//背景线条