当前位置: 首页 > news >正文

Axios 取消请求的演进:CancelToken vs. AbortController

CancelToken(早期 Axios 取消方案)

Axios 早期使用 CancelToken 来实现请求取消,其核心是一个基于 Promise 的取消机制。我之前的文章有写

随着 Fetch API 的普及,浏览器引入了 AbortController,Axios 从 v0.22.0 开始支持该方案。下面就针对最新的AbortController做分享。

1. AbortController取消请求的基本原理

Axios 使用 AbortController 来实现请求取消功能。其核心机制是:

  1. 为每个请求创建一个 AbortController 实例
  2. 将控制器的 signal 附加到请求配置中
  3. 需要取消时调用控制器的 abort() 方法

2. 代码实现解析

2.1 请求拦截器设置

request.js 中,我们设置了请求拦截器来管理请求取消:

// 存储所有活动的 AbortController
const activeRequests = new Map();request.interceptors.request.use((config) => {const requestId = generateRequestId(config);// 取消重复请求if (activeRequests.has(requestId)) {activeRequests.get(requestId).abort('取消重复请求');}// 创建并存储新的控制器const controller = new AbortController();activeRequests.set(requestId, controller);// 附加 signal 到请求config.signal = controller.signal;return config;
});

2.2 响应拦截器清理

请求完成后需要清理控制器:

request.interceptors.response.use((response) => {const requestId = generateRequestId(response.config);activeRequests.delete(requestId); // 清理控制器return response;
}, (error) => {// 错误处理
});

2.3 生成唯一请求ID

为了正确识别和取消特定请求,我们需要为每个请求生成唯一ID:

export function generateRequestId(config) {const params = JSON.stringify(config.params || {});const data = JSON.stringify(config.data || {});return `${config.url}-${config.method.toLowerCase()}-${params}-${data}`;
}

2.4 手动取消请求

提供手动取消请求的接口:

export function cancelRequest(requestId) {if (activeRequests.has(requestId)) {activeRequests.get(requestId).abort('用户手动取消');activeRequests.delete(requestId);}
}

3. 实际应用示例

3.1 流式请求中的取消

aiAgent.js 中,我们实现了流式请求的处理和取消:

export function qwenTalk(data, onProgress) {const config = {url: '/api/chat',method: 'POST',data,responseType: 'text'};currentRequestConfig = config;// 重置状态buffer = '';lastPosition = 0;return request({...config,onDownloadProgress: (progressEvent) => {// 处理流数据},})
}// 取消当前请求
export function cancelQwenTalk() {if (currentRequestConfig) {const requestId = generateRequestId(currentRequestConfig);cancelRequest(requestId);currentRequestConfig = null;}
}

3.2 使用示例

// 发起请求
const requestPromise = qwenTalk({message: 'Hello'}, (data) => {console.log('收到数据:', data);
});// 取消请求
cancelQwenTalk();

4. 关键点总结

  1. 唯一请求标识:通过 URL、方法、参数和数据生成唯一ID,确保能准确识别请求
  2. 控制器管理:使用 Map 存储所有活动的 AbortController
  3. 自动取消:在请求拦截器中自动取消重复请求
  4. 手动取消:提供接口让开发者可以手动取消特定请求
  5. 资源清理:请求完成后及时清理控制器,避免内存泄漏
  6. 流式处理:对于流式请求,需要额外管理状态(如 buffer 和 position)

5. 最佳实践

  1. 对于耗时请求(如大文件上传/下载、流式响应)一定要实现取消功能
  2. 页面/组件卸载时取消所有未完成的请求
  3. 用户导航离开时考虑取消不必要的请求
  4. 对于表单提交等场景,可以防止重复提交

6. 注意事项

  1. 取消请求后,Axios 会抛出 CancelError,需要适当处理
  2. 确保请求ID生成逻辑覆盖所有可能影响请求唯一性的因素
  3. 在单页应用中,组件卸载时要清理相关请求
http://www.xdnf.cn/news/867493.html

相关文章:

  • 【读代码】从预训练到后训练:解锁语言模型推理潜能——Xiaomi MiMo项目深度解析
  • 【android bluetooth 协议分析 12】【A2DP详解 2】【开启ble扫描-蓝牙音乐卡顿分析】
  • 光伏防逆流控制方案
  • .NET Core接口IServiceProvider
  • Spring Boot MVC自动配置与Web应用开发详解
  • Asp.net Core 通过依赖注入的方式获取用户
  • 全志A40i android7.1 调试信息打印串口由uart0改为uart3
  • 六种高阶微分方程的特解(原创:daode3056)
  • Java观察者模式深度解析:构建松耦合事件驱动系统的艺术
  • NC28 最小覆盖子串【牛客网】
  • 基于Axure+墨刀设计的电梯管理系统云台ERP的中保真原型图
  • Apache APISIX
  • CMake入门:3、变量操作 set 和 list
  • 深度学习项目之RT-DETR训练自己数据集
  • 通过模型文件估算模型参数量大小
  • Flask框架详解:轻量高效的Python Web开发利器
  • 深入解析Oracle SQL调优健康检查工具(SQLHC):从原理到实战优化
  • intense-rp-api开源程序是一个具有直观可视化界面的 API,可以将 DeepSeek 非正式地集成到 SillyTavern 中
  • Windows系统工具:WinToolsPlus 之 SQL Server Suspect/质疑/置疑/可疑/单用户等 修复
  • stress 服务器压力测试的工具学习
  • linux操作系统---网络协议
  • LeetCode 3370.仅含置位位的最小整数
  • 二维 根据矩阵变换计算镜像旋转角度
  • 短剧+小说网盘搜索系统(支持全网网盘转存拉新)
  • 《T/CI 404-2024 医疗大数据智能采集及管理技术规范》全面解读与实施分析
  • [ Qt ] | 与系统相关的操作(二):键盘、定时器、窗口移动和大小
  • 虚拟机CentOS 7 网络连接显示“以太网(ens33,被拔出)“、有线已拔出、CentOS7不显示网络图标
  • 【Unity】R3 CSharp 响应式编程 - 使用篇(集合)(三)
  • Async-profiler 内存采样机制解析:从原理到实现
  • Elasticsearch中什么是分析器(Analyzer)?它由哪些组件组成?