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

如何在React/Gatsby中实现多请求并处理返回结果

问题描述

我正在尝试在Gatsby应用中实现多数据库请求并展示结果,目前已实现单请求的可行方案,代码如下:

const ListRezept = (props) => {

const url_id = props.params.id;
const [data, setData] = useState(null);
const [isPending, setIsPending] = useState(true);
const [error, setError] = useState(null);

 useEffect(() => {
    const abortCont = new AbortController();

    setTimeout(() => {
    fetch('https://abc.4.azurestaticapps.net/data-api/rest/Rezept?$filter=RezeptId eq '+ url_id)
       .then(res => {
          if (!res.ok) { // error coming back from server
            console.log("error");
            throw Error('Could not fetch the data for that resource!');
          } 
          return res.json();
       })
       .then(data => {
        setIsPending(false);
        setData(data.value);
        setError(null);
       })
       .catch(err => {
        if (err.name === 'AbortError') {
          console.log('fetch aborted')
        } else {
          // auto catches network / connection error
          setIsPending(false);
          setError(err.message);
        }
       });
 }, []);

     // abort the fetch
     return () => abortCont.abort();
    }, []) 
    
 ...
   
 }

现在我想集成Promise.all函数来发起多请求,但不知道如何处理Promise.all的多个返回结果,尝试的失败代码如下:

const rezeptreq = fetch('https://abc.4.azurestaticapps.net/data-api/rest/Rezept?$filter=RezeptId eq '+ url_id);
const rezeptartreq = fetch('https://abc.4.azurestaticapps.net/data-api/rest/Rezeptart');

Promise.all([rezeptreq, rezeptartreq])
       .then(([res1, res2 ]) => {
     
          if (!res1.ok) { // error coming back from server
            console.log("error");
            throw Error('Could not fetch the data for that resource!');
          } 
          return res.json(), res2.json();

...

我的需求是将每个请求的结果映射到变量中,请问是否需要创建数组?该如何访问每个请求的单独结果?

解决方案

核心逻辑

Promise.all会等待所有传入的Promise完成后,返回一个包含所有结果的数组。你需要先逐个处理每个fetch的响应状态,解析JSON,再将结果分别存入对应的状态变量即可,无需额外创建数组存储。

完整可运行代码

const ListRezept = (props) => {
  const url_id = props.params.id;
  // 为每个请求的结果声明独立状态
  const [rezeptData, setRezeptData] = useState(null);
  const [rezeptartData, setRezeptartData] = useState(null);
  const [isPending, setIsPending] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const abortCont = new AbortController();
    const signal = abortCont.signal;

    // 封装单个请求逻辑:包含状态检查和JSON解析
    const getRezept = () => {
      return fetch(`https://abc.4.azurestaticapps.net/data-api/rest/Rezept?$filter=RezeptId eq ${url_id}`, { signal })
        .then(res => {
          if (!res.ok) throw Error('获取Rezept数据失败');
          return res.json();
        });
    };

    const getRezeptart = () => {
      return fetch('https://abc.4.azurestaticapps.net/data-api/rest/Rezeptart', { signal })
        .then(res => {
          if (!res.ok) throw Error('获取Rezeptart数据失败');
          return res.json();
        });
    };

    // 并行发起多个请求
    Promise.all([getRezept(), getRezeptart()])
      .then(([rezeptResult, rezeptartResult]) => {
        // 解构结果,分别存入对应状态
        setRezeptData(rezeptResult.value);
        setRezeptartData(rezeptartResult.value);
        setIsPending(false);
        setError(null);
      })
      .catch(err => {
        if (err.name === 'AbortError') {
          console.log('请求已取消');
        } else {
          setIsPending(false);
          setError(err.message);
        }
      });

    // 组件卸载时取消所有请求
    return () => abortCont.abort();
  }, [url_id]); // 依赖url_id,参数变化时自动重新请求

  // 渲染逻辑
  if (error) return <div>错误提示:{error}</div>;
  if (isPending) return <div>加载中...</div>;

  return (
    <div className="rezept-container">
      <h3>Rezept详情</h3>
      {rezeptData && <div>{JSON.stringify(rezeptData)}</div>}
      <h3>Rezeptart列表</h3>
      {rezeptartData && <div>{JSON.stringify(rezeptartData)}</div>}
    </div>
  );
};

关键细节说明

  1. 独立状态管理:为每个请求的结果创建单独的useState变量,后续可以直接通过rezeptData和rezeptartData访问各自的结果,无需额外数组。
  2. 请求封装:把每个请求的逻辑封装成函数,统一处理响应状态校验和JSON解析,避免重复代码,也方便后续维护。
  3. AbortController全局控制:将signal传入所有fetch请求,确保组件卸载时所有未完成的请求都能被取消,避免内存泄漏。
  4. 结果解构:在Promise.all的then回调中,使用数组解构语法[rezeptResult, rezeptartResult]直接获取每个请求的解析后结果,对应顺序就是传入Promise.all的请求顺序。
  5. 错误统一处理:任何一个请求失败都会触发catch块,你可以根据错误信息区分不同请求的失败原因,也可以统一展示错误提示。

你之前代码的问题修正

  • 错误使用逗号运算符:return res.json(), res2.json()只会返回最后一个JSON解析结果,正确做法是用Promise.all([res1.json(), res2.json()])并行解析两个响应。
  • 遗漏第二个请求的状态检查:需要对res2也做res2.ok的判断,否则第二个请求失败时不会抛出错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 19:04:53