CancelToken
这是axios暴露出来的一个方法,让请求进入abort状态,官网例子:
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function (thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// handle error
}
});
axios.post('/user/12345', {
name: 'new name'
}, {
cancelToken: source.token
})
// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');
还有第二种用法
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();
将其作为一个构造方法,然后传入一个方法,方法会回调一个参数,这个参数就是让那该请求取消的回调。
请求拦截器中处理重复请求
因为请求的url+params加上request的method,肯定是唯一的,所以我们用这个作为请求的唯一id,得出如下
// 记录存储的对象
const pendingRequest = new Map();
// 参数1 配置
function removePending(config) {
const {
method,
params,
baseURL,
data,
} = config;
const url = [method, params, baseURL, data].join('&');
if (pendingRequest.has(url)) {
const cancel = pendingRequest.get(url);
cancel();
}
}
function addPending(config) {
const {
method,
params,
baseURL,
data,
} = config;
let query = [];
let payload = [];
if (params) {
query = Object.entries(params).map((item) => `${item[0]}=${item[1]}`);
}
if (data) {
payload = Object.entries(params).map((item) => `${item[0]}=${item[1]}`);
}
const url = [method, baseURL].concat(query).concat(payload).join('&');
if (!pendingRequest.has(url)) {
// eslint-disable-next-line no-param-reassign
config.cancelToken = new CancelToken(((c) => {
// executor 函数接收一个 cancel 函数作为参数
pendingRequest.set(url, c);
}));
}
}
axios.interceptors.request.use(
config => {
addPending(config);
return config;
}
);
这样,就能在每一次请求中记录中不同的请求,并且标记起来了
返回拦截器中删除重复请求对象
需要注意,在response中需要删除掉该唯一的key,不然下一次新的请求进来同样会被干掉,不合理。
axios.interceptors.response.use(
response => {
removePending(response.config);
},
error => {
removePending(error.config);
return Promise.reject(error);
}
);
在成功和失败后都需要删掉该key,因为这个请求的生命周期已经结束了,删除掉保证下一次请求是正常的。