React异步fetch请求randomuser.me接口报503错误且返回undefined如何解决
问题原因
- 异步函数未等待执行结果:
fetchDriver是异步函数,返回值为Promise对象,你在do循环中直接调用fetchDriver()未加await关键字,拿到的不是实际的用户数据,后续访问driver.name.first属于读取Promise对象不存在的属性,自然返回undefined。 - 链式调用返回值错误:你在fetch的链式调用中写了
.then((data) => console.log(data)),console.log的默认返回值为undefined,这会直接覆盖前面的返回值,导致最终拿到的结果为undefined。 - 状态码分支覆盖不全:你仅处理了200和503两种响应状态码,接口返回其他4xx、5xx状态码时,第一个then块没有返回值,后续链式调用拿到的data自然为undefined。
- 重试逻辑存在漏洞:catch块中调用
fetchDriver()时没有return,重试的结果无法传递到外层,也会导致最终返回值为undefined。 - 循环逻辑不可控:do-while循环不会等待异步操作完成就执行下一轮,会同时发起大量请求,容易触发接口限流,也会导致数组计数逻辑完全混乱。
修复方案
首先调整fetchDriver的逻辑,补全错误处理、增加重试次数限制避免死循环:
// 配置最大重试次数,避免接口持续报错时进入死循环 const MAX_RETRY = 5; const driverUrl = 'https://randomuser.me/api'; async function fetchDriver(retryCount = 0) { try { const response = await fetch(driverUrl); // 处理503重试 if (response.status === 503) { if (retryCount >= MAX_RETRY) throw new Error('503错误重试次数已达上限'); // 增加阶梯延迟重试,避免短时间高频请求触发更严格的限流 await new Promise(resolve => setTimeout(resolve, 1000 * (retryCount + 1))); return fetchDriver(retryCount + 1); } // 所有非成功响应直接抛出错误 if (!response.ok) throw new Error(`请求失败,状态码:${response.status}`); const data = await response.json(); console.log(data); // 直接返回用户数据,randomuser.me的结果默认在results数组第一项 return data.results[0]; } catch (err) { console.error('请求出错:', err); if (retryCount >= MAX_RETRY) throw err; await new Promise(resolve => setTimeout(resolve, 1000 * (retryCount + 1))); return fetchDriver(retryCount + 1); } }
其次改造循环逻辑,必须等待异步请求完成后再执行后续操作:
const fetchedCars = []; async function generateCarData() { while (fetchedCars.length < 20) { // 如果fetchGeoPosition、fetchPhoneNumber等也是异步函数,同样需要加await const geoPosition = fetchGeoPosition(); const phoneNumber = fetchPhoneNumber(); const licenseNumber = fetchLicense(3); const speed = fetchSpeed(60, 200); // 必须加await等待fetchDriver返回实际用户数据 const driver = await fetchDriver(); const first = driver.name.first; const last = driver.name.last; fetchedCars.push({ licenseNumber, first, last, phoneNumber, geoPosition, speed, favorite: false, more: false, }); } // 所有数据生成完成后可在此处执行后续逻辑 console.log('20条车辆数据生成完成:', fetchedCars); } generateCarData();
内容的提问来源于stack exchange,提问作者Bartosz Król
相关产品推荐
相关产品推荐

