likes
comments
collection
share

本地接口创建与模块化防抖——实现接口节流,千度搜索功能

作者站长头像
站长
· 阅读数 23

背景

在搜索场景中应用防抖(Debounce)和节流(Throttle)技术,主要是为了优化用户体验和系统性能,尤其是在处理用户连续输入、滚动事件或其它可能高频触发的交互时。当用户在搜索框中输入关键词时,如果不加以控制,每次击键都可能触发一次搜索请求。这种情况下,如果用户输入速度较快,可能会在短时间内产生大量不必要的搜索请求,不仅浪费服务器资源,增加服务器负担,还会导致网络拥堵,同时前端界面也可能因为频繁的更新而出现卡顿。

今天我将带大家手搓一个千度模块,并在这里面加入防抖功能来减少向API接口的请求次数达到节流的效果。 如下图展示效果: 本地接口创建与模块化防抖——实现接口节流,千度搜索功能

自定义好调用的接口

这里我使用的是自定义的网络接口,教大家一个使用本地服务设置本地接口

server服务代理创建

首先我们创建一个json文件作为我们的本地上传仓库,里面的数据都是json格式,接着 将准备好的数据进行导入:

本地接口创建与模块化防抖——实现接口节流,千度搜索功能

然后打开控制台终端

npm init -y

初始化文件,接着

npm i json-server

安装json-server模块,安装成功后回到package.json文件下找到script对象下的test修改

本地接口创建与模块化防抖——实现接口节流,千度搜索功能

本地接口创建与模块化防抖——实现接口节流,千度搜索功能

最后在终端输入

npm run dev

这些数据便被你上传到本地的localhost//:3000上了,你具体使用那个端口只需要使用/{键名}来进行信息获取。 本地接口创建与模块化防抖——实现接口节流,千度搜索功能

我们创建一个网页看一下能否发出请求:

本地接口创建与模块化防抖——实现接口节流,千度搜索功能

json-server是一个非常实用的Node.js模块,它能够快速搭建一个基于JSON文件的REST API服务器。这对于前端开发者来说特别有用,因为它简化了开发过程中模拟后端数据交互的过程,使得前端开发者可以在没有实际后端服务器的情况下,进行页面功能的开发和测试。

如果你的3000端口被占用了,你还可以通过命令行参数自定义端口、中间件以及其他设置,例如

json-server local.json --port 5000

搜索防抖实现

先看一下我们的主体结构:

<template>
  <div class="container">
    <div class="title">Qian<img src="./material/Du.png" />千度</div>
    <div>
      <input type="text" id="kw" v-model="search" @keyup="debounce()">
      <button class="s_btn">千度一下</button>
    </div>
    <div>
      <ul>
        <li v-for="(item,index) in InfoList" :key="index">{{ item.name }}   年龄{{ item.age }}</li>
      </ul>
    </div>
  </div>
</template>

//script中的定义数据

import { ref,reactive} from "vue";
const InfoList = reactive([]);
let search=ref('');
const aimURL ="https://mock.mengxuegu.com/mock/66827a8052478524c838bb14/example_copy_copy/";

实现节流

    const throttle=(func,daly)=>{
      // last为我们保存上一次执行时间 deferTimer 定时器id
      let last,deferTimer  //自由变量
      //事件的处理函数
      //定义时,生成时 func daly
      //keyup return func 调用时才能找到闭包中的只有变量
        return (args)=>{
          // 对当前事件进行隐式类型转换
          let now=+new Date()
          if(last&&now<last+daly){
            //距离上次触发间隔时间小于dely
            clearTimeout(deferTimer)
            deferTimer=setTimeout(()=>{
              last=now// 不加上这个代码它还是在第一次触发后的时间执行
              func(args)
            },daly)
          }else{
            last=now  //第一次时间
            func(args)  //先执行一次
          }
        }
    }
    inputa.addEventListener("keyup",(e)=>{
      ajax(e.target.value)
    })

    //只生成一次
    const throttledFunc=throttle(ajax,1000)
    inputc.addEventListener("keyup",(e)=>{
      let value = e.target.value
      // googleSuggest 体验 ,1000
      //qps 服务器并发量
      throttledFunc(value)    //解耦
    })

请求函数getList()

实现服务代理后,我们创建一个vue文件来实现千度搜索优化。首先我们根据刚刚的API接口文件数据返回值来设置请求函数:

function getList(url) {
   InfoList.splice(0)//每次键盘该改变清除上一次给InfoList加入的值
fetch(url)
    .then((data) => data.json())
    .then((data) => {
         const filterUsers = Array.from(data.Info).filter(data => {
          if(search.value.trim()=='')  //清除两端的空格操作,并判空
              return 0
          else
            return data.name.includes(search.value.trim())//使用es6新方法includes
          })
       InfoList.push(...filterUsers) //加入搜索到的值
    });
}

防抖函数 debounce()

传统意义上的防抖常常通过setTimeout函数来实现。防抖的基本原理是限制某个函数在一定时间内只能执行一次,如果在这个时间间隔内多次触发该函数,则重新开始计时。

function debounce() {
        clearTimeout(getList.id)  //保证只执行最后一次
        //挂载在对象getList.id上 getList是闭包中的自由变量
        getList.id = setTimeout(() => {
          getList(aimURL)
        }, 500);
    }

getList函数身上挂载着用来存储setTimeout返回的ID的变量,这样减去了从外部引入变量的操作,优点是保持了数据的封装性,避免了全局变量的使用,使得防抖逻辑更加模块化和易于管理。getList不仅是一个执行获取列表操作的函数,还通过.id属性携带了关于当前延时调用的信息。

500毫秒延迟,getList函数执行前的等待时间。也就是说,如果用户在500毫秒内连续触发了多次操作,那么只有最后一次操作会在停止触发后的500毫秒后执行,达到了减少不必要的函数调用、提高性能的目的,减轻了API接口的依赖。

总结

在搜索功能中采用防抖和节流策略,可以根据具体需求平衡用户体验和系统负载。防抖更适用于那些需要在用户操作结束后再执行的操作,以避免不必要的中间状态处理;而节流则适合需要持续响应用户操作,但又需限制执行频率的场景。合理利用这两种技术,可以显著提升搜索功能的响应速度和整体性能。

转载自:https://juejin.cn/post/7386514632725495842
评论
请登录