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。

相关推荐
浪客川3 分钟前
【百例RUST - 015】闭包
开发语言·后端·rust
1314lay_10073 分钟前
匿名插槽和具名插槽的使用
前端·javascript·vue.js
Acnidouwo5 分钟前
QT程序的dpi导致显示异常处理方法
开发语言·qt
初心未改HD7 分钟前
Python零基础到精通教程,数据分析(数据处理,挖掘价值)
开发语言·python
aq553560010 分钟前
HTML头部元信息避坑指南
前端·html
tmacfrank15 分钟前
Kotlin 协程十一 —— 协作、互斥锁与共享变量
java·开发语言·kotlin
lsx20240616 分钟前
Perl 哈希
开发语言
A923A20 分钟前
Vue 和 React 常用脚手架工具总结
前端·vue.js·react.js·脚手架
skywalk816320 分钟前
CherryStudioWeb:一个优雅的 AI 聚合导航页,让你在一个页面访问所有主流 AI 服务。
前端·css·人工智能·html