前端项目中经常遇到请求输入查找场景,防抖与截流很好处理了频繁输入问题,但是不能解决最先发起请求结果后返回,覆盖了最后一次的搜索结果,导致搜索结果不正确。我总结一下自己常用的两种方法。
- 使用时间戳来过滤返回结果,如果请求回调函数中的时间戳小于当前时间戳则返回,说明已经处理了之后的请求结果了,这个请求过时了。
// 远程搜索商品
searchGoods(data) {
if (!data) {
return
}
if (this.isRemote) {
const reqCount = new Date().getTime()
this.OrderInquireQuerySpuAndUnit({ keyWord: data }).then(res => {
if (reqCount < this.currentReqCount) {
return
}
if (res.data) {
if (res.data.length > 0) {
this.goodsList = res.data
}
}
}).catch(err => {
console.log(err)
}).finally(() => {
this.currentReqCount = reqCount
})
}
},
- 基于axios封装统一的请求方法,后面发起的请求会取消之前等待返回结果的请求,需要多传一个cancelTokenPath,表示当前同一个输入组件发起的请求
export const getRequest = param => {
const { cancelTokenPath, ...restQuery } = (param && param.query) || {}
// cancelTokenPath是为了避免页面中多处请求的同一个接,导致错误的取消
if (cancelTokenPath) {
const CancelToken = axios.CancelToken
const source = CancelToken.source()
if (store[cancelTokenPath]) {
store[cancelTokenPath].cancel('Canceled by the last request')
}
store[cancelTokenPath] = source
}
return new Promise((resolve, reject) => {
Vue.axios
.get(param.url, {
params: restQuery || {},
headers: param.headers || {},
cancelToken: cancelTokenPath && store[cancelTokenPath].token
})
.then(res => { resolve(res) })
.catch(err => {
reject(err)
})
})
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。