ToB企服应用市场:ToB评测及商务社交产业平台

标题: Axios取消哀求:AbortController [打印本页]

作者: 立聪堂德州十三局店    时间: 2024-7-14 19:09
标题: Axios取消哀求:AbortController
AbortController

   AbortController() 构造函数创建了一个新的 AbortController 实例。MDN官网给出了一个利用AbortController取消下载视频的例子。
         核心逻辑是:利用AbortController接口的只读属性signal标记fetch哀求;然后在需要取消哀求的时候,调用AbortController接口的abort()方法立即取消哀求,并抛出一个错误AbortError。
  1. const controller = new AbortController();
  2. const signal = controller.signal;
  3. const url = "video.mp4";
  4. const downloadBtn = document.querySelector(".download");
  5. const abortBtn = document.querySelector(".abort");
  6. downloadBtn.addEventListener("click", fetchVideo);
  7. abortBtn.addEventListener("click", () => {
  8.   controller.abort();
  9.   console.log("Download aborted");
  10. });
  11. function fetchVideo() {
  12.   fetch(url, { signal })
  13.     .then((response) => {
  14.       console.log("Download complete", response);
  15.     })
  16.     .catch((err) => {
  17.       console.error(`Download error: ${err.message}`);
  18.     });
  19. }
复制代码
只读属性signal

        AbortController接口的只读属性 signal 返回一个 AbortSignal 实例对象,该对象可以根据需要处理 DOM 哀求通讯,既可以创建通讯,也可以终止通讯。
方法:abort()

        AbortController接口的 abort() 方法会在 DOM 哀求完成之前中止它。它可以或许中止 fetch 哀求、各种响应主体或者流的消耗。
取消Axios哀求

   既然 AbortController接口的 abort() 方法可以终止fetch哀求、各种响应主体或者流的消耗,那么我们思量将其和axios联合,来取消axios的哀求。
          查看axios官网,也给出了干系先容:

        为了便于在项目中利用,我们在对其举行一个简朴的封装,示比方下:
  1. //axios配置
  2.         function createRequest() {
  3.             const request = axios.create({
  4.                 baseURL: "https://geo.datav.aliyun.com",
  5.                 headers: {
  6.                     "Content-Type": "application/json;charset=utf-8",
  7.                 }
  8.             })
  9.             const cachePool = new Map()
  10.             const encode = (baseURL, method, url, params) => {
  11.                 const str = `${baseURL}_${url}_${method}_${JSON.stringify(params || {})}`;
  12.                 const encoder = new TextEncoder();
  13.                 //接受一个字符串作为输入,返回一个包含 UTF-8 编码的文本的 Uint8Array
  14.                 const bytes = encoder.encode(str)
  15.                 //使用Base64编码算法进行编码:将一个二进制字符串(例如,将字符串中的每一个字节都视为一个二进制数据字节)编码为 Base64 编码的 ASCII 字符串
  16.                 const encoded = btoa(String.fromCharCode(...bytes))
  17.                 return encoded
  18.             }
  19.             /**
  20.              * 对Axios请求实例的config进行编码
  21.              * */
  22.             const configEncode = (config) => {
  23.                 //获取基本信息
  24.                 const baseURL = config.baseURL,
  25.                     method = config.method,
  26.                     url = config.url,
  27.                     params = config?.params || config?.data || {};
  28.                 //返回编码结果
  29.                 return encode(baseURL, method, url, params);
  30.             }
  31.             //请求拦截器
  32.             request.interceptors.request.use(
  33.                 (config) => {
  34.                     // 在发送请求之前做些什么
  35.                     console.log(config)
  36.                     const controller = new AbortController()
  37.                     config.signal = controller.signal
  38.                     //根据config配置信息进行编码
  39.                     const encodeKey = configEncode(config)
  40.                     console.log("encodeKey:", encodeKey)
  41.                     //判断请求是否存在
  42.                     if (cachePool.get(encodeKey)) {
  43.                         controller.abort()
  44.                         console.log('cachePool--cancel:', cachePool)
  45.                     } else {
  46.                         cachePool.set(encodeKey, { abort: controller })
  47.                         console.log('cachePool--set:', cachePool)
  48.                     }
  49.                     return config;
  50.                 },
  51.                 (error) => {
  52.                     // 对请求错误做些什么
  53.                     console.log(error);
  54.                     return Promise.reject(error);
  55.                 }
  56.             );
  57.             //响应拦截器
  58.             // 添加响应拦截器
  59.             request.interceptors.response.use(function (response) {
  60.                 // 2xx 范围内的状态码都会触发该函数。
  61.                 // 对响应数据做点什么
  62.                 const encodeKey = configEncode(response.config)
  63.                 console.log('response---:', response, encodeKey)
  64.                 //缓存对象
  65.                 const cacheItem = cachePool.get(encodeKey)
  66.                 if (cacheItem) {
  67.                     console.log("res-success:删除缓存对象")
  68.                     cachePool.delete(encodeKey)
  69.                 }
  70.                 return response;
  71.             }, function (error) {
  72.                 // 超出 2xx 范围的状态码都会触发该函数。
  73.                 // 对响应错误做点什么
  74.                 console.log('axios-error:', error)
  75.                 if (error.code === "ERR_CANCELED") {
  76.                     //被取消的axios请求
  77.                     console.warn(`被取消的重复请求~`)
  78.                 } else {
  79.                     //其它错误
  80.                     return Promise.reject(error);
  81.                 }
  82.             });
  83.             //返回
  84.             return request
  85.         }
复制代码
        接下来做个简朴的测试,
  1.         const request = createRequest()
  2.         const getData = () => {
  3.             return request.get("/areas_v3/bound/420800_full.json", {
  4.                 params: {
  5.                     a: 1
  6.                 }
  7.             })
  8.         }
  9.         getData().then(result => {
  10.             console.log(result)
  11.         })
  12.         getData().then(result => {
  13.             console.log(result)
  14.         })
  15.         getData().then(result => {
  16.             console.log(result)
  17.         })
复制代码
        查看实行效果:一连发送了3次哀求,后两个被取消掉,终极只有一个哀求正常返回了哀求效果。

别的取消Axios哀求的方式

        参考:Vue:Axios前端拦截器_vue axios拦截器-CSDN博客


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4