axios取消请求

Axios 取消请求

Axios 提供了两种主要的方式来取消请求:

1. 使用 CancelToken (旧版方式,已弃用但仍可用)

javascript 复制代码
const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function (thrown) {
  if (axios.isCancel(thrown)) {
    console.log('请求已取消', thrown.message);
  } else {
    // 处理其他错误
  }
});

// 取消请求
source.cancel('操作被用户取消');

2. 使用 AbortController (推荐的新方式,从 v0.22.0 开始)

‌AbortController 是 JavaScript 中用于中止异步操作的全局 API‌,通过其 signal 属性和 abort() 方法,可终止 Fetch 请求、事件监听、数据流等异步任务。

其核心能力包括统一管理多个异步操作的中止行为和简化资源清理逻辑。‌‌‌‌

‌核心概念与基础用法‌

‌组成部分‌。

AbortController 实例包含两个关键部分:

signal:一个 AbortSignal 对象,用于向异步 API 传递中止信号。‌‌‌‌

abort() 方法:触发 signal 的中止事件,标记异步操作为已中止状态。‌‌

‌基本代码结构‌。

javascript 复制代码
const controller = new AbortController();

axios.get('/user/12345', {
  signal: controller.signal
}).then(response => {
  // 处理响应
}).catch(err => {
  if (axios.isCancel(err)) {
    console.log('请求已取消:', err.message);
  } else {
    // 处理其他错误
  }
});

// 取消请求
controller.abort('操作被用户取消');

调用 abort() 后,所有关联的异步操作将立即终止并抛出 AbortError。‌‌‌‌

标题主要应用场景

网络请求控制‌

中断长时间未完成的 Fetch 请求。‌‌‌‌

避免用户重复提交请求(如搜索框输入防抖)。‌‌

‌事件监听自动清理‌

通过单个 signal 统一移除多个事件监听器,替代手动调用 removeEventListener。‌‌‌‌
‌框架集成‌

在 React 的 useEffect 钩子中集中清理副作用。‌‌

封装 Axios 请求拦截器实现全局重复请求取消。‌‌

‌使用注意事项‌

要点 说明

错误处理 需捕获 AbortError 并区分其他错误类型‌‌‌‌

兼容性 现代浏览器广泛支持,旧版本需 Polyfill‌‌‌‌

性能优化 避免滥用导致频繁请求中断,增加服务器负担‌‌‌‌

状态复用 已中止的 signal 不可重复使用,需重新创建实例‌‌

实际应用示例

在 React 组件中使用

jsx 复制代码
import React, { useEffect } from 'react';
import axios from 'axios';

function UserComponent({ userId }) {
  useEffect(() => {
    const controller = new AbortController();
    
    const fetchData = async () => {
      try {
        const response = await axios.get(`/api/users/${userId}`, {
          signal: controller.signal
        });
        // 处理数据
      } catch (err) {
        if (axios.isCancel(err)) {
          console.log('请求已取消:', err.message);
        } else {
          // 处理其他错误
        }
      }
    };
    
    fetchData();
    
    return () => {
      // 组件卸载时取消请求
      controller.abort('组件卸载,取消请求');
    };
  }, [userId]);

  return <div>用户信息展示</div>;
}

在 Vue 中取消重复请求

javascript 复制代码
// 存储所有活跃请求的控制器
const activeRequests = new Map();

// 添加请求
function addRequest(config) {
  const controller = new AbortController();
  config.signal = controller.signal;
  const url = `${config.method}:${config.url}`;
  activeRequests.set(url, controller);
  return config;
}

// 移除请求
function removeRequest(config) {
  const url = `${config.method}:${config.url}`;
  if (activeRequests.has(url)) {
    activeRequests.delete(url);
  }
}

// 取消重复请求
function cancelRequest(config) {
  const url = `${config.method}:${config.url}`;
  if (activeRequests.has(url)) {
    activeRequests.get(url).abort('取消重复请求');
    activeRequests.delete(url);
  }
}

// 请求拦截器
axios.interceptors.request.use(config => {
  cancelRequest(config); // 取消之前的相同请求
  return addRequest(config);
});

// 响应拦截器
axios.interceptors.response.use(
  response => {
    removeRequest(response.config);
    return response;
  },
  error => {
    removeRequest(error.config);
    return Promise.reject(error);
  }
);

注意事项

  1. 取消请求会触发错误,需要使用 axios.isCancel() 来区分是取消错误还是其他错误
  2. 每个请求只能取消一次
  3. 取消请求后,Promise 会被 reject
  4. 在组件卸载时取消请求是良好的实践,可以避免内存泄漏
  5. 对于频繁触发的请求(如搜索框输入),取消之前的请求可以提升性能

AbortController 是现代浏览器原生支持的标准 API,推荐使用这种方式而不是旧的 CancelToken。

相关推荐
超级大只老咪17 分钟前
HTML学习路线
前端·学习·html
゜ eVer ㄨ19 分钟前
React学习第三天——生命周期
前端·学习·react.js
almighty2721 分钟前
C# WPF实现ComboBox实时搜索与数据绑定
开发语言·c#·wpf·combobox
摆烂且佛系22 分钟前
CSS元素的总宽度计算规则
前端·css
对岸住着星星26 分钟前
vue3+ts实现拖拽缩放,全屏
前端·javascript
菜鸟小九33 分钟前
SSM(MybatisPlus)
java·开发语言·spring boot·后端
aesthetician35 分钟前
@tanstack/react-query:React 服务器状态管理与数据同步解决方案
服务器·前端·react.js
数据知道36 分钟前
Go基础:常用数学函数处理(主要是math包rand包的处理)
开发语言·后端·golang·go语言
学习同学37 分钟前
从0到1制作一个go语言服务器 (一) 配置
服务器·开发语言·golang
大飞pkz41 分钟前
【设计模式】桥接模式
开发语言·设计模式·c#·桥接模式