依托 axios 实现全局请求防抖
最近在看axios的时候发现一个之前用过的功能,但是一直没明白其中原理是什么,但是在仔细阅读了axios的api后结合之前所学,对当下的功能又有了新的理解,故又有了这篇文章。首先axios,一个依基于promise的网络请求库。防抖的话这里就不复述了,不懂的可以自己网上查。请求防抖的实现思路:定义一个全局的请求数组,每次在拦截器中判断是否有和数组中地址参数的请求,如果有就取消掉这个请求。核心api
更新:该方法已过时(此 API 自 v0.22.0 起已弃用,传送门),新的代替方案是 AbortController ,并且!前端取消请求无法真实取消,原因在于请求发送到服务器后服务器或许已经做了处理,但是前端只是关闭了返回通道,可是实际上服务器已经对该请求做了处理,所以存在风险,不建议在post接口上使用,如需实现同类功能可以让后端同学来。
原文:
最近在看axios的时候发现一个之前用过的功能,但是一直没明白其中原理是什么,但是在仔细阅读了axios的api后结合之前所学,对当下的功能又有了新的理解,故又有了这篇文章。
axios,一个依基于promise的网络请求库。防抖的话这里就不复述了,不懂的可以自己网上查。
请求防抖的实现思路:定义一个数组用来放请求函数,每次在拦截器中判断是否有和数组中地址参数的请求,如果有就取消这个请求并返回。
核心api :axios.CancelToken;
axios的介绍是这样的:
You can also create a cancel token by passing an executor function to the constructor:CancelToken
您还可以通过向构造函数传递执行函数来创建一个取消令牌:CancelToken
简单来说就是用来取消axios的请求方法的。
使用方式:
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// An executor function receives a cancel function as a parameter
cancel = c;
})
});
// cancel the request
cancel();
最后
全局请求防抖具体代码实现:
let cancelToken= axios.CancelToken;//取消api
let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
let removePending = config => {
pending.find((item,i)=>{
//判断当前请求数组中是否存在相同请求地址的接口
if(item.u===config.url + "&" + config.method){
pending[i].c(); //执行取消方法
pending.splice(i, 1); //把这条记录从数组中移除
return true;
}
})
};
//添加请求拦截器
axios.interceptors.request.use(
config => {
removePending(config); //在一个ajax发送前执行一下取消操作
config.cancelToken = new cancelToken(c => {
// 传入对比参数 和 取消方法
pending.push({ u: config.url + "&" + config.method, c });
});
return config;
},
error => {
return Promise.reject(error);
}
);
//添加响应拦截器
axios.interceptors.response.use(
response => {
//do something
},
error => {
//因为请求被取消了,响应器中会走错误流程,这里返回一下自定义格式
return {
data: {
code: 666,
cancel: true,
errorMsg: "请求已关闭"
}
};
}
);
这边还有个优化思路就是在普通项目中还好,碰到带token或者特殊的类似无序参数的请求方法,或者项目特别大的,可能会导致我们的数组的内容长度会特别长,可以尝试在相应中完成请求后删除数组中对应的请求方法,这样的话,我们数组长度就不会越来越长了,但这在小项目中,接口请求不超过四位数,或者没有那种带无序请求参数的话都还是能用的。
更多推荐
所有评论(0)