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

如何在React中使用AbortController取消Promise?实现异常问题求助

问题原因及修复方案

你的代码存在4个核心错误,逐一排查修复即可:

  • 变量名引用错误,导致signal和controller不匹配
  • Promise状态提前敲定,abort监听逻辑失效
  • React重渲染时AbortController实例被重置,前后实例不统一
  • 同步循环没有加中断检查,无法响应中途的abort操作

1. 修复变量名&稳定AbortController实例

WrapperComponent.tsx中你声明的实例名是controller,但获取signal时用了不存在的abortController,同时要使用useRef保存实例避免重渲染时生成新实例:

import { useRef } from 'react'

export const WrapperComponent = () => {
  // 用useRef保证controller实例永远不变
  const controllerRef = useRef(new AbortController());

  const doSomeStuff = (file: any): void => {
    // 每次调用前先重置实例,避免之前的abort状态影响新请求
    controllerRef.current = new AbortController();
    const signal = controllerRef.current.signal;

    calculateSomeStuff(signal, file)
      .then((hash) => {
        // 执行相关逻辑
      })
      .catch((error) => {
        if (error.name === 'AbortError') {
          // 处理取消逻辑
          return
        }
        // 处理其他错误
      });
  };

  return (<Table controller={controllerRef.current} />)
}

2. 修复calculateSomeStuff逻辑

你需要先绑定abort监听,再执行业务逻辑,同时不要提前resolve Promise,同步循环内要加中断判断:

export const calculateSomeStuff = async (signal, file): Promise<any> => {
  // 先判断是否已经被取消
  if (signal.aborted) {
    console.log('signal.aborted', signal.aborted);
    throw new DOMException('Aborted', 'AbortError');
  }

  return new Promise((resolve, reject) => {
    // 先绑定abort监听
    const abortHandler = () => {
      console.log('Aborted');
      reject(new DOMException('Aborted', 'AbortError'));
    };
    signal.addEventListener('abort', abortHandler);

    try {
      // 同步循环内加中断判断
      for (let i = 0; i <= 10; i++) {
        if (signal.aborted) return;
        // 执行相关逻辑
      }

      const secret = 'ojefbgwovwevwrf';
      console.log('Promise Started');
      resolve(secret);
    } catch (err) {
      reject(err);
    } finally {
      // 执行完成后移除监听避免内存泄漏
      signal.removeEventListener('abort', abortHandler);
    }
  });
};

3. Table组件可选优化

你定义的handleAbort接收的fileName参数没有用到,可以按需删除,本身逻辑没有错误:

export const Table = ({controller}) => {
  const handleAbort = () => {
    controller.abort();
  };

  return (
    <Button
      onClick={handleAbort}
    />
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 06:06:01