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。

相关推荐
步行cgn1 小时前
Vue 中的数据代理机制
前端·javascript·vue.js
GH小杨1 小时前
JS之Dom模型和Bom模型
前端·javascript·html
星月心城2 小时前
JS深入之从原型到原型链
前端·javascript
MessiGo2 小时前
Javascript 编程基础(5)面向对象 | 5.2、原型系统
开发语言·javascript·原型模式
你的人类朋友3 小时前
🤔Token 存储方案有哪些
前端·javascript·后端
烛阴3 小时前
从零开始:使用Node.js和Cheerio进行轻量级网页数据提取
前端·javascript·后端
liuyang___3 小时前
日期的数据格式转换
前端·后端·学习·node.js·node
西哥写代码3 小时前
基于cornerstone3D的dicom影像浏览器 第三十一章 从PACS服务加载图像
javascript·pacs·dicom
慢半拍iii3 小时前
数据结构——D/串
c语言·开发语言·数据结构·c++
爱学习的白杨树4 小时前
Sentinel介绍
java·开发语言