前言:最近有个小伙伴跟我分享了他的面试内容,提到中断接口请求,我就想起来我好像就做过这个需求,回去翻了翻项目。顺便把这个业务给记录下来,好记性不如烂笔头。
为什么要中断接口请求呢?
- 上传下载文件(视频、图片、文档等),选错了,可以在请求完成前中止请求;
- 同一个表格不同请求内容,因为请求时间快慢问题,有时候拿不到最新请求的数据,这就需要把上一个请求中止掉;
- 以便节省带宽和资源,并确保应用程序的高效性。
AbortController 这个接口是在MDN文档被我翻阅出来的,具体介绍就是
表示一个控制器对象,允许你根据需要中止一个或多个 Web 请求。
注意:
- Vue3 + axios(AbortController 终止feth请求);
- 从
v0.22.0开始,Axios 支持以 fetch API 方式——AbortController取消请求; CancelToken从v0.22.0开始已被弃用,不应在新项目中使用。- AbortController,这个规范是一个 DOM 层面的规范,不是 JavaScript 语言层面的规范。
使用
//创建一个新的 `AbortController` 对象实例。
const controller = new AbortController();
//可以用它与一个DOM请求进行通信或者中止该请求。
const { signal } = controller;
//中止一个尚未完成的web请求
controller.abort();
1、aixios拦截重复的请求
//axios有请求拦截和响应拦截,那么中止重复请求就在请求拦截里面实现。
//需要一个记录请求痕迹的变量
const reqTrace = new Map();
const getPendingUrl = (config) => {
return [config.method, config.url].join("&");
};
//移除请求
const removePending(config) {
const url = getPendingUrl(config);
if (pendingMap.has(url)) {
// 如果当前请求在等待中,取消它并将其从等待中移除
const abortController = pendingMap.get(url);
if (abortController) {
abortController.abort(url);
}
pendingMap.delete(url);
}
}
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
removePending(config);
const url = getPendingUrl(config);
const controller = new AbortController();
config.signal = controller.signal;
if (!pendingMap.has(url)) {
// 如果当前请求不在等待中,将其添加到等待中
pendingMap.set(url, controller);
}
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
在写文档之前,我也查了一下掘金的相关文档,发现比较详细的一位大佬,KirkLin,当然,每个封装都是根据业务需求出发,仅供参考。
2、中止上传下载文件请求
const controller = new AbortController();
axios.get('/foo/bar', {
signal: controller.signal
}).then(function(response) {
//...
});
// cancel the request
controller.abort()
这段代码来自于gitHub,可以前往查阅更详细内容