React中如何等待所有Axios请求完成及定位失败请求
解决React useEffect中等待所有Axios请求完成及定位失败请求的方案
一、等待所有请求完成的优化方案
原代码采用串行执行请求的方式,效率偏低。推荐通过Promise.all或Promise.allSettled实现并行请求,同时等待全部请求结束:
方案1:用Promise.all并行执行(任一失败则触发整体catch)
这种方式会同时发起所有请求,等待全部成功后再更新状态,若有任一请求失败则直接进入catch逻辑:
useEffect(() => { async function getHomePageContent() { // 并行发起所有请求 const [sliderRes, recommendedRes, mostOrderRes, mostRatedRes] = await Promise.all([ HomePageServices.getSliderContent(), HomePageServices.getRecommendedProducts(), HomePageServices.getMostOrderProducts(), HomePageServices.getMostRatedProducts() ]); // 统一更新状态 setSliderProduct(sliderRes.data); setRecommendedProducts(recommendedRes.data); setMostOrderProducts(mostOrderRes.data); setMostRatedProducts(mostRatedRes.data); } getHomePageContent().catch((error) => { console.error("请求出错:", error); }); }, []);
方案2:用Promise.allSettled执行(允许部分请求失败,获取所有请求状态)
如果希望部分请求失败不影响其他请求结果的获取,可使用Promise.allSettled,它会返回每个请求的执行状态(成功/失败):
useEffect(() => { async function getHomePageContent() { const results = await Promise.allSettled([ { name: "轮播内容", request: HomePageServices.getSliderContent() }, { name: "推荐商品", request: HomePageServices.getRecommendedProducts() }, { name: "最多订单商品", request: HomePageServices.getMostOrderProducts() }, { name: "最高评分商品", request: HomePageServices.getMostRatedProducts() } ]); // 遍历结果处理成功请求,记录失败请求 results.forEach((item) => { if (item.status === "fulfilled") { switch(item.name) { case "轮播内容": setSliderProduct(item.value.data); break; case "推荐商品": setRecommendedProducts(item.value.data); break; case "最多订单商品": setMostOrderProducts(item.value.data); break; case "最高评分商品": setMostRatedProducts(item.value.data); break; } } else { console.error(`请求【${item.name}】失败:`, item.reason); } }); } getHomePageContent(); }, []);
二、定位具体失败请求的方法
方法1:给每个请求添加错误标识(适配Promise.all场景)
在单个请求的catch中抛出带请求名称的自定义错误,这样整体catch时能直接定位失败请求:
useEffect(() => { async function getHomePageContent() { const [sliderRes, recommendedRes, mostOrderRes, mostRatedRes] = await Promise.all([ HomePageServices.getSliderContent().catch(err => { throw new Error(`轮播内容请求失败: ${err.message}`); }), HomePageServices.getRecommendedProducts().catch(err => { throw new Error(`推荐商品请求失败: ${err.message}`); }), HomePageServices.getMostOrderProducts().catch(err => { throw new Error(`最多订单商品请求失败: ${err.message}`); }), HomePageServices.getMostRatedProducts().catch(err => { throw new Error(`最高评分商品请求失败: ${err.message}`); }) ]); // 更新状态 setSliderProduct(sliderRes.data); setRecommendedProducts(recommendedRes.data); setMostOrderProducts(mostOrderRes.data); setMostRatedProducts(mostRatedRes.data); } getHomePageContent().catch((error) => { console.error(error.message); }); }, []);
方法2:利用Promise.allSettled遍历结果(最直观)
如方案2中的代码,给每个请求绑定名称后遍历结果,能直接查看每个请求的状态,精准定位失败请求,同时不影响其他成功请求的状态更新。
额外优化:简化HomePageServices代码
原服务类中的async/await可省略,因为axios.get本身返回Promise,无需额外封装:
class HomePageServices { getSliderContent() { return axios.get(`${baseURL}/slider`); } getMostRatedProducts() { return axios.get(`${baseURL}/mostRatedProducts`); } getMostOrderProducts() { return axios.get(`${baseURL}/mostOrderProduct`); } getRecommendedProducts() { return axios.get(`${baseURL}/recommendedProduct`); } }
内容的提问来源于stack exchange,提问作者asdasdas
相关产品推荐
相关产品推荐

