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

React/JavaScript如何实现多个fetch请求并分类存储返回数据

实现方案

你原有代码存在两个核心问题:

  • 在Promise.all的参数数组中给每个fetch加await,会让两个请求从并发变成串行执行,白白增加请求总耗时
  • response.json()本身返回Promise对象,你没有等待它解析完成就赋值,最终拿到的会是Pending状态的Promise,不是实际接口数据;而且普通变量赋值不会触发React组件重渲染,数据更新后页面不会同步刷新

基于useEffect+useState的标准实现

直接在useEffect里发起并发请求,用独立的useState存储不同接口的返回值即可,同时可以补充加载状态、错误处理的逻辑,适配实际业务场景:

import { useState, useEffect } from 'react';

function DataComponent() {
  // 为不同接口单独定义state,初始值可以根据接口返回类型设置为数组/空对象
  const [timeData, setTimeData] = useState([]);
  const [functionData, setFunctionData] = useState([]);
  // 可选:补充加载、错误状态,优化用户体验
  const [loading, setLoading] = useState(false);
  const [errorMsg, setErrorMsg] = useState('');

  useEffect(() => {
    // useEffect的回调不能直接声明为async,所以在内部定义异步请求函数
    const loadAllData = async () => {
      try {
        setLoading(true);
        setErrorMsg('');
        // 直接传入fetch任务实现真正并发,不要在数组内加await
        const [timeResponse, funcResponse] = await Promise.all([
          fetch('/api/time-endpoint'),
          fetch('/api/function-endpoint')
        ]);

        // fetch仅在网络异常时抛出错误,HTTP 4xx/5xx需要手动校验
        if (!timeResponse.ok) throw new Error('时间数据接口请求失败');
        if (!funcResponse.ok) throw new Error('功能数据接口请求失败');

        // 并发解析两个响应的JSON结果
        const [timeResult, funcResult] = await Promise.all([
          timeResponse.json(),
          funcResponse.json()
        ]);

        // 分别更新对应state,触发组件重渲染
        setTimeData(timeResult);
        setFunctionData(funcResult);
      } catch (err) {
        setErrorMsg(err.message);
      } finally {
        setLoading(false);
      }
    };

    loadAllData();
  }, []); // 空依赖数组表示仅在组件首次挂载时执行一次请求

  // 渲染时可以根据状态做对应处理
  if (loading) return <div>数据加载中...</div>;
  if (errorMsg) return <div>加载失败:{errorMsg}</div>;

  return (
    <div>
      {/* 后续逻辑里可以直接访问timeData、functionData使用 */}
    </div>
  );
}

可选优化点

  • 如果接口数量多,不想定义太多独立state,也可以合并为单个state对象管理:
const [apiData, setApiData] = useState({
  timeData: [],
  functionData: []
});
// 更新时
setApiData({
  ...apiData,
  timeData: timeResult,
  functionData: funcResult
});
  • 如果后续需要手动触发重新请求,只需要把loadAllData函数从useEffect中提取出来,绑定到按钮点击等事件上即可
  • 如果组件卸载时请求还没完成,可以加AbortController中断请求,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 20:09:11