防抖函数在主页中的使用

防抖与节流,看了些博客以及大厂的面试题,为一个高频考点。先对其做个总结,再将它写入实际上的目前在做的项目之中。

首先,为什么要使用防抖函数?

举一个实例来说,比如我们在某个搜索框中,比如我们想要搜索“apple”:

当我们输入a的时候,为了更好的用户体验,通常会出现对应的联想内容,这些联想内容通常是保存在服务器的,所以需要一次网络请求;

当继续输入ap的时候,再次发送网络请求;

那么apple总共需要发出5次网络请求,这会大大地损耗整个系统的性能,无论是对前端的事件处理或是对于服务器的压力。实际上,我们不需要这么多次的网络请求,正确的做法应该是,在合适的情况下再去发送网络请求。

比如说,如果用户快速的输入“apple”,那么只是发送一次网络请求,如果用户是输入a后想了一会儿,那这个时候a确实应该发送一次网络请求。简而言之,就是应该监听用户在某个时间段内,没有再次触发时,再去发送网络请求。

防抖的操作即为,只有在某个时间内,没有再次触发某个函数时,才真正的调用这个函数。

当事件触发时,相应的函数并不会被立即触发,而是会等待一定时间;当事件密集触发时,函数的触发会被频繁的延迟,只有等呆了一段时间也没有事件触发,才会真正的执行响应函数。

防抖的应用场景还是很多的,比如:

1.输入框中频繁地输入内容,搜索或者提交信息。

2.频繁地点击按钮,触发某个事件。

3.监听浏览器滚动事件,完成某些特定操作。

4.用户缩放浏览器地resize事件。

 

那么,节流是怎样呢?

预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行。就好像你在淘宝抢购某一件限量热卖商品时,你不断点刷新点购买,可是总有一段时间你点上是没有效果,这里就用到了节流,就是怕点的太快导致系统出现bug。节流的操作即为,在某个时间内,某个函数只能被触发一次。

节流的应用场景为:

1.监听页面的滚动事件。

2.鼠标移动事件。

3.用户频繁点击按钮操作。

4.游戏中的一些设计。

总而言之,依然是密集的事件触发,然而相比于防抖函数,节流不会等待最后一次才去进行函数调用,而是会按照一定的频率进行调用。

本次项目中,使用到了防抖函数,因为之前,我们监听goodsitem的时候,使用事件总线的时候,在home.vue中执行了:

mounted() {
    //3.监听item中图片加载完成
    this.$bus.$on("itemimageload",()=>{this.$refs.scroll.refresh()
    })
  }

由于主页面需要加载的商品页面比较多,频繁调用对性能无好处。因此,我在这里使用了一个防抖函数。防抖的话,我先把它封装了,代码如下:

export function debounce(func,delay){
  let timer = null
  return function (...args){
    if (timer) clearTimeout(timer)
    timer = setTimeout(()=>{
      func.apply(this,args)
    },delay)
  }
}

下面我们来,解析下上述的防抖函数。其核心思路如下:

1.当触发一个函数时,并不会立即执行这个函数,而是会延迟(通过定时器来延迟函数的执行)。

2.如果在延迟时间内,又重新触发函数,那么取消上一次的函数执行,即取消定时器。

3.如果在延迟时间内,没有重新触发函数,那么这个函数就会正常执行(执行传入的函数)。

将思路转成代码即可:

定义debounce函数要求传入两个函数:需要处理的函数func以及延迟时间。

通过定时器来延迟传入函数func的执行,如果在此期间有再次触发这个函数,那么clearTimeout取消这个定时器,如果没有触发,那么在定时器的回调函数中执行即可。

那么,接下来我们可以改动在home.vue中的代码啦~

先导入debounce函数,

import {debounce} from "../../src/components/common/utils/utils";

之后再改动mounted:

mounted() {
    const refresh = debounce(this.$refs.scroll.refresh, 200)
    this.$bus.$on("itemimageload", () => {
      refresh()
    })
  }

 

上一篇:详解防抖函数(debounce)和节流函数(throttle)


下一篇:lodash入门,使用 。throttle和debounce