还不知道axios如何取消请求吗?还在为了请求没必要继续但是还是在发送而苦恼吗?看下面解决你的烦恼:
axios之cancelToken取消请求及源码讲解
首先我们要明确:cancelToken是axios用来取消请求的API。
那为什么要取消呢?是由于浏览器的请求的响应时间存在不确定性,请求次数过多可能较早发起的请求会比较晚的响应。所以要为了提升页面性能减少不必要的等待,我们需要取消不需要等待的较早的请求。
那种过多的请求是无意义且浪费性能的呢?比如:
(1)菜单的路由页面跳转、tab栏的高频切换;
(2)搜索框的change事件模糊匹配时,短时间发送多个ajax请求,返回数据并不是最想要的。
当然了,还有很多的适用场景哦!了解的可以在评论区下方发出来,供大家学习~
注意:cancel token 并不是意义上的取消,请求还是会到服务器,只是浏览器进行处理。
那如何创建cancelToken呢?具体呢有两种写法:
第一种:使用CancelToken.source工厂方式创建canceltoken:
const cancelToken = axios.CancelToken;
const source = cancelToken.source();
axios.get('/**/**',{
cancelToken:source.token
}).catch(function(thrown)=>{
if(aixos.isCancel(thrown)){
//取消请求,打印日志
}else{
//处理错误
}
})
source.cancel("取消")//取消请求,参数可选
第二种:通过传递一个executor函数到CancelToken的构造函数来创建cancelToken
const cancelToken = axios.CancelToken;
let cancel;
axios.post("**/**",{
name:"11"
},
{
cancelToken:new cancelToken(function executor(c){
//executor 函数接收一个cancel函数作为参数
cancel = c;
})
})
cancel();//取消请求
那么我们在项目中如何应用来取消重复的请求呢?
我们可以在executor函数中将当前的请求地址,添加到一个数组中。然后等下次请求的时候,判断当前的请求是否存在:已经存在则直接取消。
这里需要注意:只使用url作为key,不惧有唯一性,也并不准确;所以我们需要使用当前请求的全部信息去生成唯一的key。
//根据当前的请求信息生成唯一的key
funciton onlyKey = function(config){
const {url,method,params,data} = config;
return `${url}${method}${JSON.stringify(params)}${JSON.stringify(data)}`
}
const pendingList = new Map();
//添加请求信息到pendingList:
function addPending (config){
config.cancelToken = new cancelToken(c=>{
if(!pendingList.has(key)){
pendingList.set(key,c)
}
})
}
//检查是否存在重复请求,存在就删除重复的请求
const removePending = (config) => {
//根据当前的请求信息生成唯一的key
if(pendingList.has(key)){
const cancelToken = pendingRequest.get(key);
cancelToken(key);
pendingRequest.delete(key);
}
})
}
注意:
(1)第一条请求永远不会被取消,因为还未将其添加到pendingList中存储。
(2)最好在路由跳转前判断如果不是当前的路由,移除当前pendingList等待的请求。
看了如何在项目中应用,还有兴趣的话跟我一起了解一下源码鸭!
var Cancel = require('./Cancel');
function CancelToken(executor) {
if (typeof executor !== 'function') {
throw new TypeError('executor must be a function.');
}
//定义resolvePromise,创建promise实例;
//将resolve赋值给resolvePromise;使得可以在promise外部改变对象的状态
var resolvePromise;
this.promise = new Promise(function promiseExecutor(resolve) {
resolvePromise = resolve;
});
//将当前CancelToken的实例赋值给token
var token = this;
//传入cancel方法,cancel方法中可以调用resolvePromise方法;来执行promise的resolve方法,改变状态
executor(function cancel(message) {
if (token.reason) {
// Cancellation has already been requested
return;
}
token.reason = new Cancel(message);
resolvePromise(token.reason);
});
}
/**
* 如果取消被请求,则抛出一个“取消”。
*/
CancelToken.prototype.throwIfRequested = function throwIfRequested() {
if (this.reason) {
throw this.reason;
}
};
//返回的对象中包含一个新的' CancelToken '和一个函数,该函数在被调用时,取消请求
CancelToken.source = function source() {
var cancel;
var token = new CancelToken(function executor(c) {
//这里的c就是CancelToken中给executor传入cancel方法
cancel = c;
});
return {
token: token,
cancel: cancel
};
};
module.exports = CancelToken;
我大概对于axios的cancelToken也就这些储备可以和大家分享了。有了解更多更清楚的大佬,欢迎在评论区指导哦!我定当虚心受教!