Jinuss's blog Jinuss's blog
首页
  • 源码合集

    • Leaflet源码分析
    • Openlayers源码合集
    • vue3源码
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

东流

Web、WebGIS技术博客
首页
  • 源码合集

    • Leaflet源码分析
    • Openlayers源码合集
    • vue3源码
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • React

  • Vue

  • JavaScript文章

    • Map和WeakMap
    • Set和WeakSet
    • ES5面向对象
    • ES6面向对象
    • 多种数组去重性能对比
    • 几个高级的JS API
    • JS随机打乱数组
    • 判断是否为移动端浏览器
    • 防抖与节流函数
    • JS获取和修改url参数
    • 比typeof运算符更准确的类型判断
    • Navigator clipboard介绍使用
    • Javascript 语法错题集
    • ESM和CommonJS详解
    • ColorThief的介绍与使用
    • new命令原理
    • 扩展运算符
    • 遍历深层对象指定层级的属性
    • 一文弄懂typeof和instanceof
    • JS中可迭代的数据类型
    • 比较两个字符串的大小
    • requestIdleCallback
    • undefined和void
    • axios取消http请求
      • 前言
      • 问题解决
  • 学习笔记

  • openlayers

  • threejs

  • MapboxGL

  • 工具

  • 源码合集

  • ECMAScript历年新特性

  • 前端
  • JavaScript文章
东流
2025-09-08
目录

axios取消http请求

# 前言

在前端项目中,经常用axios作为http请求接口的插件。

在开发中,我们考虑如下三种场景:

(1)固然可以通过防抖亦或是节流,限制用户在频繁点击按钮的场景下http请求的次数。那么,如果前一个http请求已经发出了,那么如何取消它呢?

(2)或者在另一种场景下,如果接口响应不是那么及时,第一次请求还在pending状态;第二次请求的参数和第一次不同,第一次请求的结果返回了,但是第二次请求还在pending,我们拿到的数据其实不是我们想要的。

(3)还有一种场景,如果在页面卸载或者组件时,某些还在pending状态的http请求是无效的,纯属浪费资源。

以上三种场景的相同点就是需要取消pending状态的http请求。

# 问题解决

在Web API中,MDN文档中写道:

AbortController 接口表示一个控制器对象,允许你根据需要中止一个或多个 Web 请求。 你可以使用 AbortController() 构造函数创建一个新的 AbortController 对象。使用 AbortSignal 对象可以完成与异步操作的通信

基于AbortController,我们可以封装一个apiController类。在axios的request拦截器中比对,控制器集合对象中是否存在相同的控制器,如不存在,则添加当前http请求的相关信息,一个请求对应生成一个控制器对象controller;若存在,则调用控制器,取消前一个请求,添加新的控制器;在response拦截器中移除对应的控制器。

apiController类封装如下:

export class ApiController {
    constructor() {
        this.controllerMap = new Map()
    }
    // 获取控制器对象
    getControllerMap() {
        return this.controllerMap;
    }
    // 创建请求的唯一标识
    createRequestId(config) {
        const { method, url, data } = config;
        return `${method}${url}${JSON.stringify(data)}`;
    }

    // 取消待处理请求
    cancelPendingRequest(requestId, reason) {
        const controllerMap = this.getControllerMap();

        // 如果已存在相同请求,取消旧请求
        controllerMap.get(requestId).abort(reason);
        controllerMap.delete(requestId);
    }


    // 添加请求到待处理列表
    addRequestToQueue(config) {
        const controllerMap = this.getControllerMap();
        const requestId = this.createRequestId(config);
        if (controllerMap.has(requestId)) {
            // 如果已存在相同请求,取消旧请求
            this.cancelPendingRequest(requestId, '重复请求,取消前一次')
        }

        const controller = new AbortController();
        config.signal = controller.signal;
        controllerMap.set(requestId, controller);
    }

    // 移除待处理列表
    removeRequestFromQueue(config) {
        const requestId = this.createRequestId(config);
        const controllerMap = this.getControllerMap();
        if (controllerMap.has(requestId)) {
            controllerMap.delete(requestId);
        }
    }

    // 清除所有的控制器
    clear() {
        const controllerMap = this.getControllerMap();
        controllerMap.clear();
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

ApiController类使用如下

const apiController = new ApiController();

const service = axios.create();

service.interceptors.request.use((config)=>{
    apiController.addRequestToQueue(config)

    return config;
})

service.interceptors.response.use((response)=>{
    apiController.removeRequestFromQueue(response.config)

    return response;
},error(error)=>{
    if (axios.isCancel(error)) {
      apiController.removeRequestFromQueue(error.config)
    } else{
       /**其他错误处理 */ 
    }
})


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
编辑 (opens new window)
上次更新: 2025/09/08, 03:11:23
undefined和void
《JavaScript高级程序设计》笔记

← undefined和void 《JavaScript高级程序设计》笔记→

最近更新
01
directive自定义指令实现原理
09-12
02
scheduler调度器
09-10
03
watch和watcherEffect源码解析
09-09
更多文章>
Theme by Vdoing | Copyright © 2024-2025 东流 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式