本地接口创建与模块化防抖——实现接口节流,千度搜索功能
背景
在搜索场景中应用防抖(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