记录一次防抖与搜索的结合使用

262 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

经常看到与防抖和节流有关的文章,但一直没有机会用上。最近,有项目要在搜索框上要加一个自动搜索的功能,即用户输入搜索内容之后,不必按下回车或者搜索按钮,程序自动搜索,但不可能用户每输入一个字符就进行一次搜索,那样开销会变得比较大,也有会产生一些其他问题。
这不就是使用防抖的绝佳条件,因此用本文记叙一些开发要点。

技术栈

vue3

分析

实现自动搜索,如果用户每输入一次,都发送一个搜索请求,那么有可能造成以下问题:

1.短时间内请求太多,额外开销大,做了许多无用功。可以说,在用户输入完成之前,前面所有的搜索请求都是无用的,只有在用户输入完成后,获取到完整的搜索关键词后发送的搜索请求所返回的内容,才是用户真正想看的。
2.请求返回时间不确定。这是之前遇到的一个问题,有两个请求先后发送,但是后面发起的请求反而先返回,不知道这个是为什么。但用在自动搜索这里,万一先发起的请求返回的比较慢,有可能导致页面展示的搜索内容与实际用户搜索的不符。
但实际上,前端也无法确定用户什么时候输入完成,所以,我个人的做法就是设定一个时间间隔,在设定的时间间隔内,用户没有继续输入呢内容,视为输入完成,然后发起搜索请求,这也是防抖的基本思路。

防抖

众所周知,防抖的存在就是为了节省开销,把多个重复的操作合并成一个操作。具体来说就是,发起的操作请求不要立即执行,创建一个定时器进行存储;如果在定时器的操作请求还没有执行前,又发起了一个相同的操作请求,那么取消已有的定时器,重新创建一个定时器,以此类推,简易版示例代码如下:

let timer = 0

/**
  * 防抖函数
  * @param { Number } 执行延迟时间
  */
function debounce (delay = 500) {
    // 如果存在定时器,则取消
    timer && clearTimeout(timer)
    // 开启新的定时器
    timer = setTimeout(() => {
        doSomething()
    }, delay)
}

看上去逻辑有点复杂,但是实现起来十分简单。

防抖与搜索

搜索与防抖的结合也是比较简单的。
1.首先,需要监听输入框的input事件。

<input v-model="searchWord" @input="handleSearch"  />

2.定义一个带防抖的搜索函数, 500毫秒内用户没有继续输入内容,发起搜索请求:

let timer = 0

/** 搜索函数 */
function handleSearch() {
    timer && clearTimeout(timer)
    timer = setTimeout(() => {
        search()
    }, 500)
}

效果: 动画.gif