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

React中请求持续被取消问题:Axios+AbortController异常排查

问题分析与解决:AbortController取消请求后后续请求失效

问题根源

你使用的AbortController是单例实例,一旦调用abort(),这个控制器就会进入永久终止状态,后续所有复用该控制器signal的请求都会直接被取消,甚至无法发起。

修复方案

核心是每次取消请求后,必须创建新的AbortController实例,同时完善loading状态的管理逻辑:

修改Gallery组件代码

const controller = useRef<AbortController>(new AbortController());
const loading = useRef(false);
const [page, setPage] = useState(1);

const search = () => {
  if(loading.current) return;
  loading.current = true; // 请求开始时标记加载中
  dispatch(search(params, controller.current.signal));
}

const cancelSearch = () => {
  if(loading.current){
    controller.current.abort();
    // 关键:重新创建新的AbortController实例
    controller.current = new AbortController();
    loading.current = false;
  }
}

const pageClick = (selection) => {
  cancelSearch();
  setPage(selection);
  search();
}

// 注意:需要在请求完成(成功/失败)的回调中重置loading状态
// 例如在组件接收请求结果的地方:
// useEffect(() => {
//   // 假设请求结果通过redux状态获取
//   if (requestFinished) {
//     loading.current = false;
//   }
// }, [requestFinished]);

修改Actions代码(补充错误处理)

const search = (params, signal) => async (dispatch) => {
  try {
    const response = await axios.get(`${url}${params}`, {signal: signal});
    // 处理请求成功逻辑,比如更新画廊数据
    dispatch({ type: 'SEARCH_SUCCESS', payload: response.data });
  } catch (error) {
    // 捕获请求取消的错误,避免控制台报错
    if (axios.isCancel(error)) {
      console.log('请求已取消');
      return;
    }
    // 处理其他请求错误
    dispatch({ type: 'SEARCH_ERROR', payload: error.message });
  } finally {
    // 可以在这里通知组件请求已结束,或者由组件自行监听状态变化
    dispatch({ type: 'SEARCH_FINISHED' });
  }
}

额外说明

  • AbortController是一次性的,终止后无法复用,必须重新实例化才能发起新的请求。
  • 务必保证loading.current在请求开始、结束、取消三个时机都正确更新,避免出现请求阻塞或重复发起的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 14:35:07