取消axios请求

方案 1:使用 AbortController(推荐,符合标准)

Axios 从 0.22.0 版本开始支持原生 AbortController,替代旧的 CancelToken(已标记为废弃),步骤如下:

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

const RequestComponent = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    // 1. 创建 AbortController 实例
    const controller = new AbortController();
    const signal = controller.signal;

    // 2. 发起请求时传入 signal
    const fetchData = async () => {
      setLoading(true);
      try {
        const res = await axios.get('https://api.example.com/data', {
          signal: signal, // 关联取消信号
        });
        setData(res.data);
      } catch (error) {
        // 3. 捕获取消请求的错误(避免控制台报错)
        if (axios.isCancel(error)) {
          console.log('请求已取消:', error.message);
        } else {
          console.error('请求失败:', error);
        }
      } finally {
        setLoading(false);
      }
    };

    fetchData();

    // 4. 组件卸载/依赖更新时取消请求(useEffect 清理函数)
    return () => {
      controller.abort('组件卸载,取消请求'); // 取消请求并传入提示信息
    };
  }, []);

  return (
    <div>
      {loading ? <p>加载中...</p> : <pre>{JSON.stringify(data, null, 2)}</pre>}
    </div>
  );
};

export default RequestComponent;

方案 2:使用 CancelToken(兼容旧版本)

若项目中 Axios 版本低于 0.22.0,可使用 CancelToken,步骤如下:

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

const RequestComponent = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    // 1. 创建 CancelToken 和取消函数
    const CancelToken = axios.CancelToken;
    let cancel;

    const fetchData = async () => {
      setLoading(true);
      try {
        const res = await axios.get('https://api.example.com/data', {
          cancelToken: new CancelToken((c) => {
            cancel = c; // 保存取消函数
          }),
        });
        setData(res.data);
      } catch (error) {
        if (axios.isCancel(error)) {
          console.log('请求已取消:', error.message);
        } else {
          console.error('请求失败:', error);
        }
      } finally {
        setLoading(false);
      }
    };

    fetchData();

    // 2. 清理函数中执行取消
    return () => {
      if (cancel) cancel('组件卸载,取消请求');
    };
  }, []);

  return (
    <div>
      {loading ? <p>加载中...</p> : <pre>{JSON.stringify(data, null, 2)}</pre>}
    </div>
  );
};

export default RequestComponent;

关键注意事项

  1. 清理时机 :取消请求必须放在 useEffect 的清理函数中,确保组件卸载 / 依赖更新时触发,避免内存泄漏。

  2. 错误捕获 :取消请求会抛出异常,需用 axios.isCancel(error) 判断并过滤,避免控制台报错。

  3. 手动取消 :若需要手动触发(如点击按钮取消),可将 controller 或 cancel 函数存入 useRef,示例:

    ini 复制代码
    const controllerRef = useRef(null);
    
    // 发起请求时
    controllerRef.current = new AbortController();
    
    // 手动取消按钮
    const handleCancel = () => {
      if (controllerRef.current) {
        controllerRef.current.abort('手动取消请求');
      }
    };
相关推荐
可乐鸡翅yeah_9 小时前
FFmpeg 生成 HLS 独立分片 independent‑segments 参数到底有什么用
javascript·ffmpeg·音视频·safari·m3u8
福兮说9 小时前
canvas 旋转图片的六个坑:四角被裁、Math.ceil 多出 1px 黑边、JPG 角发黑、翻转方向反了
前端·javascript·图像处理·canvas
Ai-_Man11 小时前
您您这可以把Grok的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。AI导出鸭
javascript·人工智能·ai·小程序·电脑
传人once11 小时前
多图片上传预览功能如何写
前端·css·html·jquery·html5
Eric.4611 小时前
Wan‑Animate+MiniMax-H3 本地部署 AI 漫剧流水线:8G 显存动作迁移与动态分镜工程实战
前端·人工智能·comfyui·ai漫剧
liangshanbo121511 小时前
JavaScript 异步核心主线
javascript·事件循环·异步操作
传人once12 小时前
悬停旋转放大和位移效果如何写
javascript·css·动画
库拉镜像AI牛牛13 小时前
短剧内容自动化生产:知漫剧工作室落地教程
大数据·服务器·前端·人工智能·语音识别
律宏阔13 小时前
Flutter 列表图片内存优化:CachedNetworkImage 与 ClipRRect 的取舍
前端·flutter
行者全栈架构师13 小时前
【鸿蒙心迹】相册文搜图工程化落地:HarmonyOS 7.0 端侧 AI 检索全链路实战与 5 个踩坑解法
前端