React中为API请求实现50秒超时处理方案问询
实现50秒超时机制的具体方案
核心思路
用Promise.race()让API请求和50秒定时Promise"赛跑",只要定时Promise先完成,就触发超时逻辑——关闭当前加载弹窗、打开超时弹窗。同时要清理定时器,避免内存泄漏。
步骤1:封装通用超时逻辑
先写一个可复用的超时处理片段,用来生成50秒后触发的Promise:
const getTimeoutPromise = () => { let timer; const promise = new Promise((_, reject) => { timer = setTimeout(() => reject(new Error('请求超时')), 50000); }); return { promise, timer }; };
步骤2:改造invokeFeesScreen调用逻辑
在TestApp.js中调用invokeFeesScreen时,用Promise.race()包裹请求和超时Promise,处理所有分支逻辑:
// 假设这是触发invokeFeesScreen的业务函数 const callFeesScreen = async () => { // 开启加载状态(如果需要) setFeeLoading(prev => ({...prev, showFeeLoading: true})); const { promise: timeoutPromise, timer } = getTimeoutPromise(); try { // 同时执行API请求和超时逻辑 const response = await Promise.race([ invokeFeesScreen(), // 你的API服务调用 timeoutPromise ]); // 请求成功:关闭加载弹窗,处理返回数据 setFeeLoading(prev => ({...prev, showFeeLoading: false})); console.log('Fees请求成功:', response); } catch (error) { setFeeLoading(prev => ({...prev, showFeeLoading: false})); if (error.message === '请求超时') { // 触发超时弹窗 setFeeTimeout(prev => ({...prev, showFeeTimeout: true})); } else { // 处理接口返回的错误码等常规错误 console.error('Fees请求失败:', error); } } finally { // 无论结果如何,清理定时器 clearTimeout(timer); } };
步骤3:复用逻辑处理invokeSignatureScreen
针对invokeSignatureScreen,直接套用相同模式,替换对应的状态更新即可:
const callSignatureScreen = async () => { // 假设对应加载状态的setter是setSignatureLoading,超时状态是setSignatureTimeout setSignatureLoading(prev => ({...prev, showSignatureLoading: true})); const { promise: timeoutPromise, timer } = getTimeoutPromise(); try { const response = await Promise.race([ invokeSignatureScreen(), timeoutPromise ]); setSignatureLoading(prev => ({...prev, showSignatureLoading: false})); console.log('签名请求成功:', response); } catch (error) { setSignatureLoading(prev => ({...prev, showSignatureLoading: false})); if (error.message === '请求超时') { setSignatureTimeout(prev => ({...prev, showSignatureTimeout: true})); } else { console.error('签名请求失败:', error); } } finally { clearTimeout(timer); } };
额外注意事项
- 如果是函数组件,在组件卸载时要清理未完成的定时器,可以用
useEffect的清理函数:useEffect(() => { const activeTimers = []; // 在调用API时,把timer存入activeTimers数组 // ... return () => { activeTimers.forEach(timer => clearTimeout(timer)); }; }, []); - 确保状态更新的逻辑和你现有代码的状态结构一致,比如
setFeeLoading和setFeeTimeout的用法要匹配项目中的状态定义。
内容的提问来源于stack exchange,提问作者sarad
相关产品推荐
相关产品推荐

