如何在外部类中中止独立文件内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
相关产品推荐
相关产品推荐

