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

如何在外部类中中止独立文件内fetch请求的AbortController?

实现外部中止封装在独立函数中的fetch请求

问题分析

原getInfoReq函数将AbortController封装在内部,外部无法访问;加上重试逻辑会每次新建控制器,导致外部无法中止正在进行(包括重试中)的请求。需要调整函数结构,暴露中止能力并维护当前有效的控制器。

修改请求函数getInfoReq

调整函数使其返回包含请求Promise和中止方法的对象,同时维护最新的请求控制器:

export default function getInfoReq({zon, mc, pc}) {
  let url = '/getInfo';
  let currentController; // 维护当前生效的请求控制器
  let options = {
    method: "POST",
    headers:{
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      "o": zon,
      "m": mc,
      "p": pc
    })
  };

  const fetchData = async (retries) => {
    currentController = new AbortController(); // 每次重试更新控制器
    const optionsWithSignal = {
      ...options,
      signal: currentController.signal
    };

    try {
      let timer = setTimeout(() => currentController.abort(), 5000);
      let response = await fetch(url, optionsWithSignal);
      clearTimeout(timer);
      if(response.ok) return response.json();
    } catch(e) {
      console.log(e);
      if(retries <= 1) {
        return { message: "something went wrong" };
      }
      return await fetchData(retries - 1);
    } 
  };

  const requestPromise = fetchData(2);

  return {
    promise: requestPromise,
    abort: () => currentController?.abort() // 暴露中止方法,可选链避免空值报错
  };
}

在类A中调用并实现中止

在类中保存请求控制对象,点击取消按钮时调用中止方法,并处理中止后的错误:

class A extends React.Component {
  constructor(props) {
    super(props);
    this.currentRequest = null; // 存储当前请求的控制对象
  }

  async triggerRequest() {
    // 先中止之前未完成的请求
    if (this.currentRequest) {
      this.currentRequest.abort();
    }

    // 发起新请求并保存控制对象
    this.currentRequest = getInfoReq({ zon: o, mc: mc, pc: pc });
    try {
      const jsonString = await this.currentRequest.promise;
      // 处理请求返回的数据
      console.log(jsonString);
    } catch (e) {
      // 区分请求中止错误和其他错误
      if (e.name === 'AbortError') {
        console.log("请求已被手动中止");
      } else {
        console.log("请求失败:", e);
      }
    } finally {
      this.currentRequest = null; // 请求结束后清空
    }
  }

  handleCancel() {
    // 调用中止方法并清空请求对象
    if (this.currentRequest) {
      this.currentRequest.abort();
      this.currentRequest = null;
    }
  }

  render() {
    return (
      <div>
        <Button onClick={() => this.triggerRequest()}>发起请求</Button>
        <Button onClick={() => this.handleCancel()}>CANCEL</Button>
      </div>
    );
  }
}

关键说明

  • 用currentController维护每次重试后的最新控制器,确保调用abort时能中止当前正在进行的请求。
  • 请求函数返回的abort方法直接操作当前控制器,将中止能力暴露给外部调用方。
  • 类中维护currentRequest对象,确保可以追踪并中止未完成的请求,同时避免重复请求冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 10:42:49