您现在的位置是:首页 >技术交流 >bug 记录 - 接口被重复调用,响应时长不同,结果被覆盖的问题网站首页技术交流
bug 记录 - 接口被重复调用,响应时长不同,结果被覆盖的问题
简介bug 记录 - 接口被重复调用,响应时长不同,结果被覆盖的问题
发现问题与调试过程
- 需求:输入框中输入关键字,根据关键字去调用接口,返回模糊查询的结果集合。
- 问题:输入的关键字越少,接口响应时间越长。
- 例如:输入“阿”,接口响应时间大概是 5 秒,紧接着输入“阿周”,接口响应时间大概是 2 秒。
- 呈现的结果就是,在第 2 秒的时候,第二次模糊搜索的结果返回,列表内容是“阿周”相关,在第 5 秒的时候,第一次模糊搜索的结果返回,列表内容是“阿”相关。最终呈现的结果集(“阿”相关结果)与搜索框的内容(“阿周”)不一致
代码复现
<van-field
v-model="filterCheckProvider"
placeholder="请输入关键字"
@input="filterFunc"
/>
// 绑定输入框的 @input 事件,添加节流函数
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; // 查询到结果后,赋值
// 第 2 秒时,得到结果 arrA
// 第 5 秒时,得到结果,覆盖上次结果 arrB
}
}).catch((err)=>{})
}
解决思路
- 最开始的思路是,前端发送请求时,多添加一个参数 nowTime,取值为发送请求时的时间戳,后端拿到 nowTime ,不做改变,只做传递,和数据结果一起返回。前端拿到响应数据后,对比多次 nowTime,取最晚时间的 nowTime 对应的值。
- 第二种思路,一位同事提出的,很玄妙!在接口的响应体中判断 params.filterText 与 this.filterText 是否一致,如果两者一致,表示当前返回结果与输入框内容一致,是最新结果,需要渲染。如果两者不一致,说明当前返回结果与输入框内容不一致,不能渲染。
修改代码
<van-field
v-model="filterCheckProvider"
placeholder="请输入关键字"
@input="filterFunc"
/>
// 绑定输入框的 @input 事件,添加节流函数
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)=>{})
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。