如何使用 Axios 的 AbortController 取消请求

1,960 阅读2分钟

Axios 是一个非常流行的 JavaScript 库,用于进行 HTTP 请求。它提供了许多便利的功能,例如拦截器、Promise API 和并发请求控制等。在使用 Axios 发送请求时,有时我们需要取消请求,以便节省带宽和资源,并确保应用程序的高效性。

在过去,Axios 提供了 CancelToken API 来取消请求。但是从 v0.22.0 开始,Axios 支持使用 fetch API 的 AbortController API 来取消请求。本文将介绍如何使用 AbortController 来取消 Axios 请求,并给出一个封装 AbortController 的实现。

使用 AbortController 取消 Axios 请求

AbortController 是一个在现代浏览器中内置的 API,用于取消任何正在进行的请求。Axios 提供了一个 signal 选项来使用 AbortController API。

传送至官网: 取消请求 | Axios Docs (axios-http.com)

下面是如何在 Axios 请求中使用 AbortController :

 const controller = new AbortController();
 ​
 axios.get('/foo/bar', {
    signal: controller.signal
 }).then(function(response) {
    //...
 });
 ​
 // 取消请求
 controller.abort();

通过使用 AbortController 的实例,我们可以在需要时调用 abort() 方法来取消请求。

在 Axios 中,我们可以将 AbortControllerAxiosRequestConfigsignal 选项一起使用。

具体来说,我们可以为每个请求创建一个 AbortController 实例,并将其添加到请求配置中,以便我们可以随时取消请求。

封装 AbortController 的示例:

 import type { AxiosRequestConfig } from "axios";
 ​
 // 用于存储每个请求的标识和取消函数
 const pendingMap = new Map<string, AbortController>();
 ​
 const getPendingUrl = (config: AxiosRequestConfig): string => {
   return [config.method, config.url].join("&");
 };
 ​
 export class AxiosCanceler {
   /**
    * 添加请求
    * @param config 请求配置
    */
   public addPending(config: AxiosRequestConfig): void {
     this.removePending(config);
     const url = getPendingUrl(config);
     const controller = new AbortController();
     config.signal = controller.signal;
     if (!pendingMap.has(url)) {
       // 如果当前请求不在等待中,将其添加到等待中
       pendingMap.set(url, controller);
     }
   }
 ​
   /**
    * 清除所有等待中的请求
    */
   public removeAllPending(): void {
     pendingMap.forEach((abortController) => {
       if (abortController) {
         abortController.abort();
       }
     });
     this.reset();
   }
 ​
   /**
    * 移除请求
    * @param config 请求配置
    */
   public removePending(config: AxiosRequestConfig): void {
     const url = getPendingUrl(config);
     if (pendingMap.has(url)) {
       // 如果当前请求在等待中,取消它并将其从等待中移除
       const abortController = pendingMap.get(url);
       if (abortController) {
         abortController.abort(url);
       }
       pendingMap.delete(url);
     }
   }
 ​
   /**
    * 重置
    */
   public reset(): void {
     pendingMap.clear();
   }
 }

以上提供的代码实现了一个基本的AxiosCanceler类。这个类可以用来取消正在进行的请求。在这个类中,我们创建了一个pendingMap对象,它用于存储每个请求的标识和取消函数。当请求被发出时,我们将其添加到pendingMap中。如果需要取消请求,我们可以使用AbortController.abort()方法取消请求。

在AxiosCanceler类中,我们定义了addPending、removeAllPending和removePending三个方法。addPending方法用于将请求添加到pendingMap中。removeAllPending方法可以用于取消所有请求,而removePending方法可以用于取消单个请求。

完整代码示例:celeris-admin/packages/web/request/src at master · kirklin/celeris-admin (github.com)

总结

如果你在你的应用程序中需要管理多个请求,并且需要在请求发出后取消这些请求,那么AxiosCanceler类将是一个非常有用的工具。它可以让你更好地控制你的异步请求,并避免一些不必要的错误。