You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多API调用场景下如何正确控制页面加载器的显隐?

问题描述

我创建了一个状态变量:

let [isLoading, setIsLoading] = useState(false)

需要调用三个API,对应的函数如下:

const api1 = ()=>{
 setIsLoading(true)
 callApi()
 setIsLoading(false)
}

const api2 = ()=>{
 setIsLoading(true)
 callApi()
 setIsLoading(false)
}

const api3 = ()=>{
 setIsLoading(true)
 callApi()
 setIsLoading(false)
}

我在useEffect()中调用这三个函数,使用axios发起API请求。当前问题是任意一个API调用成功后,就会执行setIsLoading(false),导致加载器提前停止,而此时另外两个API尚未完成。

我需要实现加载器在所有API调用完成后才停止,UI中通过isLoading && <Loader />渲染加载器。

我知道一种解决方案是创建三个状态变量,通过(isLoading1 || isLoading2 || isLoading3) && <Loader />来控制,但不想创建多个状态,请问有没有更好的处理加载动画的方式?

解决方案

方案1:使用Promise.all()统一管理请求

只保留单个isLoading状态,将所有API请求包装为Promise,通过Promise.all()等待全部请求完成后再关闭加载状态,适合需要同时发起所有请求的场景。

修改后的代码示例:

const fetchAllData = async () => {
  setIsLoading(true);
  try {
    // 传入所有API请求的Promise(axios请求本身返回Promise)
    await Promise.all([
      callApi(), // 对应原api1的请求逻辑
      callApi(), // 对应原api2的请求逻辑
      callApi()  // 对应原api3的请求逻辑
    ]);
  } catch (error) {
    // 统一处理请求错误
    console.error('API请求失败:', error);
  } finally {
    // 无论成功或失败,最终关闭加载状态
    setIsLoading(false);
  }
};

// 在useEffect中触发统一请求
useEffect(() => {
  fetchAllData();
}, []);

注意事项:

  • Promise.all()会在任意一个请求失败时立即进入catch块;如果允许部分请求失败,可替换为Promise.allSettled(),它会等待所有请求完成(无论成败)后再执行后续逻辑。
  • 确保每个callApi返回的是Promise,axios的请求默认满足此要求。

方案2:用计数器跟踪请求进度

如果需要灵活控制API的调用时机(非同时发起),可以用计数器记录未完成的请求数,仅当计数器归0时才关闭加载状态,同时保留单个isLoading变量。

代码示例:

const [isLoading, setIsLoading] = useState(false);
const [pendingCount, setPendingCount] = useState(0);

// 封装通用请求处理函数
const handleApiCall = async (apiFn) => {
  setPendingCount(prev => prev + 1);
  // 首次请求时开启加载
  if (!isLoading) setIsLoading(true);

  try {
    await apiFn();
  } catch (error) {
    console.error('请求出错:', error);
  } finally {
    setPendingCount(prev => {
      const newCount = prev - 1;
      // 所有请求完成后关闭加载
      if (newCount === 0) setIsLoading(false);
      return newCount;
    });
  }
};

// 重写原API调用函数
const api1 = () => handleApiCall(callApi);
const api2 = () => handleApiCall(callApi);
const api3 = () => handleApiCall(callApi);

// 在useEffect中调用三个API
useEffect(() => {
  api1();
  api2();
  api3();
}, []);

这个方案支持分批调用API的场景,比如用户操作触发单个API时,也能准确维护加载状态,无需新增多个isLoading变量。


内容的提问来源于stack exchange,提问作者Varun Deva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 09:06:35