You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重置AbortController值:React+Axios下载场景的边缘问题

解决AbortController复用导致重复终止请求的问题

之前用useRef保存AbortController的方案能应对常规场景,但在下载弹窗的场景下存在问题:用户点击下载打开进度模态框,关闭弹窗时终止请求,但再次点击下载时,新请求会直接被终止——因为组件没重新渲染,ref里的AbortController实例还是之前被abort过的,对应的signal处于终止状态。

原问题代码

AbortController ref定义

let controller = useRef(new AbortController()).current;

关闭模态框终止请求函数

const closeModal = () => {
  // 关闭模态框逻辑
  controller.abort()
}

下载请求函数

const downloadFile = async (type) => {
  // 一些逻辑
  const res = await axios({
    url: "https://www.something.com",
    onDownloadProgress: (progressEvent) => {
      // 进度计算逻辑    
    },
    signal: controller.signal
  })
}

修复方案

核心思路是每次发起下载请求时,重新创建AbortController实例,替换ref中的旧实例,确保每次请求用的都是未被终止的新signal。

修改后的代码

AbortController ref定义

const controllerRef = useRef(new AbortController());

关闭模态框终止请求函数

const closeModal = () => {
  // 关闭模态框逻辑
  controllerRef.current.abort();
}

下载请求函数(关键修改)

const downloadFile = async (type) => {
  // 每次发起请求前,重置为新的AbortController实例
  controllerRef.current = new AbortController();
  
  // 一些逻辑
  try {
    const res = await axios({
      url: "https://www.something.com",
      onDownloadProgress: (progressEvent) => {
        // 进度计算逻辑    
      },
      signal: controllerRef.current.signal
    });
    // 请求成功后的处理逻辑
  } catch (error) {
    // 捕获请求取消的错误,避免控制台报错
    if (axios.isCancel(error)) {
      console.log("下载已取消");
    } else {
      // 处理其他下载错误
      console.error("下载失败", error);
    }
  }
}

这样修改后,每次点击下载都会生成新的AbortController,之前的终止操作不会影响到新请求,完美解决重复终止的问题。

内容的提问来源于stack exchange,提问作者labs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 09:40:24