项目场景
需求:模糊搜索边输入变查询(假设输入很快,输入之后500ms请求一次),查询条件越多查询结果越快(符合条件的数据越少啊)
问题:有时候上一次输入请求的结果非常慢(还未返回),然鹅我输入的一下个查询请求已经返回了(第二次请求的接口比上一次快),那么显示的查询结果就是上一次的查询结果,说到底就是查错了,这样的用户会懵逼啊;
其他应用场景:适用于任何接口请求频繁(如也适用于重复提交,只取最后一个有效的,其余取消请求;比如切换菜单更新对应菜单下的商品,切换第二个的时候上一个还未返回(它们的商品装在同一个篮框里的)
【注意】:重复提交或者切换操作一般都很快,所以可能上一次发出的还没返回你就发了第二次,这种情况就取消上一次,如果网够快或者性能够好上一次的已经返回了,你才发的第二次那么取消请求就不会执行了
如何解决?
在输入一下个查询的时候,如果上一个请求接口未完成,直接将上一个未完成的查询请求中断取消。
axios官网给出了取消请求的方法:axios.CancelToken
官网地址:www.axios-js.com/zh-cn/docs/…
//本文只对模糊搜索接口进行中断上一次请求的处理,如需对全部接口进行处理,去掉拦截器的if条件限制即可
// 取消请求
const CancelToken = axios.CancelToken;
let axiosCancel:any = null //定义存放取消的请求方法
/**
* 创建 axios 实例
*/
const service = axios.create({
timeout: 3000,
withCredentials: true
})
/**
* req 拦截器
*/
let requestText:any;
service.interceptors.request.use((config: any): object => {
if (config.params && config.params.searchingText) {
//模糊查询的时候避免输入太快,直接取最后一次请求返回的结果
requestText = config.params.searchingText;
if(typeof axiosCancel === 'function'){
//在请求发出前取消上一次未完成的请求
axiosCancel('终止请求'); //取消请求
}
config.cancelToken = new CancelToken(function executor(c:any) {
axiosCancel = c;
});
}
return config
}, (error: any): object => {
return Promise.reject(error)
})
/**
* res 拦截器
*/
let responseText:any;
service.interceptors.response.use((response: any) => {
if (response.config.params && response.config.params.searchingText) {
responseText = response.config.params.searchingText;
axiosCancel = null
}
const res = response.data
return Promise.resolve(res)
},(err:any)=>{
if (axios.isCancel(err)) {
console.log('Rquest canceled:', err.message); //请求如果被取消,这里是返回取消的message
} else {
if (err && err.response) {
switch (err.response.status) {
case 401:
Logout({}).then((res:any)=>{
location.href = res;
})
}
}
return Promise.reject(err)
}
})
//封装GET,POST,PUT,DELETE,PATCH请求
export const GetBuilder = (url:any, params = {}) => {
return service.get(url, {params:params})
}
export const DeleteBuilder = (url:any, params = {}) => {
return service.delete(url,{params:params})
}
export const PatchBuilder = (url:any,data = {},params={}) => {
return service.patch(url,data,{params:params})
}
export const PostBuilder = (url:any,data = {},params={}) => {
return service.post(url, data,{params:params})
}
export const PutBuilder = (url:any,data = {},params={}) => {
return service.put(url, data,{params:params})
}