发现问题与调试过程
- 需求:输入框中输入关键字,根据关键字去调用接口,返回模糊查询的结果集合。
- 问题:输入的关键字越少,接口响应时间越长。
- 例如:输入“阿”,接口响应时间大概是 5 秒,紧接着输入“阿周”,接口响应时间大概是 2 秒。
- 呈现的结果就是,在第 2 秒的时候,第二次模糊搜索的结果返回,列表内容是“阿周”相关,在第 5 秒的时候,第一次模糊搜索的结果返回,列表内容是“阿”相关。最终呈现的结果集(“阿”相关结果)与搜索框的内容(“阿周”)不一致
代码复现
<van-field
v-model="filterCheckProvider"
placeholder="请输入关键字"
@input="filterFunc"
/>
filterFunc() {
this.debounce(() => {
this.searchFunc();
this.timmer = null;
}, 800);
},
debounce(func, delay) {
return (() => {
if (this.timmer) {
clearTimeout(this.timmer);
}
this.timmer = setTimeout(func, delay);
})();
},
searchFunc() {
let params = {
filterText: this.filterText,
};
searchFunc(params).then((res)=>{
if(res && res.code==200) {
this.result = res.data;
}
}).catch((err)=>{})
}
解决思路
- 最开始的思路是,前端发送请求时,多添加一个参数 nowTime,取值为发送请求时的时间戳,后端拿到 nowTime ,不做改变,只做传递,和数据结果一起返回。前端拿到响应数据后,对比多次 nowTime,取最晚时间的 nowTime 对应的值。
- 第二种思路,一位同事提出的,很玄妙!在接口的响应体中判断 params.filterText 与 this.filterText 是否一致,如果两者一致,表示当前返回结果与输入框内容一致,是最新结果,需要渲染。如果两者不一致,说明当前返回结果与输入框内容不一致,不能渲染。
修改代码
<van-field
v-model="filterCheckProvider"
placeholder="请输入关键字"
@input="filterFunc"
/>
filterFunc() {
this.debounce(() => {
this.searchFunc();
this.timmer = null;
}, 800);
},
debounce(func, delay) {
return (() => {
if (this.timmer) {
clearTimeout(this.timmer);
}
this.timmer = setTimeout(func, delay);
})();
},
searchFunc() {
let params = {
filterText: this.filterText,
};
searchFunc(params).then((res)=>{
if(res && res.code==200) {
if(params.filterText == this.filterText) {
this.result = res.data;
}else {
}
}
}).catch((err)=>{})
}