中断接口请求AbortController

193 阅读2分钟

前言:最近有个小伙伴跟我分享了他的面试内容,提到中断接口请求,我就想起来我好像就做过这个需求,回去翻了翻项目。顺便把这个业务给记录下来,好记性不如烂笔头。

为什么要中断接口请求呢?

  1. 上传下载文件(视频、图片、文档等),选错了,可以在请求完成前中止请求;
  2. 同一个表格不同请求内容,因为请求时间快慢问题,有时候拿不到最新请求的数据,这就需要把上一个请求中止掉;
  3. 以便节省带宽和资源,并确保应用程序的高效性。

AbortController 这个接口是在MDN文档被我翻阅出来的,具体介绍就是

表示一个控制器对象,允许你根据需要中止一个或多个 Web 请求。

注意:

  1. Vue3 + axios(AbortController 终止feth请求);
  2. 从 v0.22.0 开始,Axios 支持以 fetch API 方式—— AbortController 取消请求;
  3. CancelToken 从 v0.22.0 开始已被弃用,不应在新项目中使用。
  4. 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,可以前往查阅更详细内容