React中如何基于try/catch与Promise实现接口500错误重试?
接口返回500错误时的高效重试方案
针对接口500错误(服务器端临时故障),最可行的方案是实现带指数退避的重试逻辑,既保证请求有机会成功,又不会因频繁重试给服务器造成额外压力。同时结合AbortController处理组件卸载或依赖变化时的请求取消,避免竞态问题。
步骤1:封装通用重试函数
先写一个可复用的重试工具函数,核心逻辑是捕获请求错误,判断是否为500状态码,若满足则按指数退避延迟后重试,直到达到最大重试次数:
const retryWithExponentialBackoff = async ( requestFn, maxRetries = 3, initialDelay = 1000 // 初始延迟1秒 ) => { let attempt = 0; while (attempt < maxRetries) { try { // 每次重试创建新的AbortController,避免取消后续请求 const controller = new AbortController(); const result = await requestFn(controller.signal); return result; } catch (error) { attempt++; // 根据API错误结构判断是否为500错误 if (error.response?.status !== 500 || attempt >= maxRetries) { throw error; // 非500错误或达到重试上限,抛出错误 } // 指数退避:延迟时间随重试次数翻倍 const delay = initialDelay * Math.pow(2, attempt - 1); await new Promise(resolve => setTimeout(resolve, delay)); } } };
步骤2:改造原有useEffect逻辑
将原API调用替换为调用重试函数,同时处理依赖变化时的请求取消:
useEffect(() => { const controller = new AbortController(); const fetchData = async () => { setIsLoadingGraph(true); try { setCSV(createPayload()); const response = await retryWithExponentialBackoff(async (signal) => { // 传递AbortSignal给API请求,支持取消操作 return api.generateDataByFilters(createPayload(), { signal }); }); response.data.itens.forEach((data) => { setDataTable(data.detail); setDataGraph(data.summarizedBySenderNumber); setTotalDispatchMessages(data.totalDispatchMessages); setTotalSentMessages(data.totalSentMessages); setTotalReceivedMessages(data.totalReceivedMessages); setTotalReadMessages(data.totalReadMessages); setTotalFailedMessages(data.totalFailedMessages); setTotalBillableMessages(data.totalBillableMessages); }); } catch (error) { // 忽略请求取消的错误 if (error.name !== 'AbortError') { console.error(error); } } finally { setIsLoadingGraph(false); } }; fetchData(); // 组件卸载或依赖更新时取消未完成的请求 return () => controller.abort(); }, [periodFilter, originFilter, senderFilter, endDateTime, initialDateTime]);
关键说明
- 指数退避:每次重试的延迟时间翻倍,避免短时间内大量请求冲击服务器,比如第1次等1秒、第2次等2秒、第3次等4秒。
- 错误判断:需根据你的API错误响应结构调整判断逻辑(比如
error.response?.status === 500),确保只重试服务器临时错误。 - 请求取消:使用
AbortController在组件卸载或依赖更新时取消未完成的请求,防止过时请求更新状态导致页面异常。
内容的提问来源于stack exchange,提问作者Guilherme Abel
相关产品推荐
相关产品推荐

