从循环中的两个 API 获取并合并

Fetch from two APIs in loop and combine

我正在尝试做我认为非常简单的事情,但结果却非常困难。本质上我想做的是在加载页面时循环遍历 ID 数组,为每个 ID 调用两个 APIs,将每个 ID 的响应合并在一起,并将其保存到 React 状态变量itemList.

这是我目前的代码。 getInfo()getOtherInfo() 两个函数正在执行基本的 JavaScript Fetch 并返回 Promise,然后异步解码 JSON 数据没问题。我什至可以在页面加载时显示返回的数据,所以这部分工作正常。

useEffect(() => {
  idList.forEach((id) => {
    getInfo(id)
      .then((response) => {
        getOtherInfo(id).then((otherReponse) => {
          response.otherInfo = otherResponse;
        });
        setItemList((itemList) => [...itemList, response]);
      })
      .catch((error) => console.log("Loading failed: " + error));
  });
}, []);

我知道嵌套 .then() 是错误的,因为它试图将响应数据添加到可能未解决的 Promise,但这是我第一次使用 React Hooks 和 Fetch API 所以我'我不确定 正确 的方法是什么。我发现了其他几个类似的问题,但它们似乎没有处理从两个 APIs 返回后将数据连接在一起的问题。

有人能给我指出正确的方向吗?

试试这个

var promiseArr = [];    
idList.forEach((id) => {
  promiseArr.push(getInfo(id));
    promiseArr.push(getOtherInfo(id));
});

Promise.all(promiseArr).then((resp) => {
   console.log(resp);
}).catch((error) => console.log("Loading failed: " + error));

I know that the nested .then() is wrong, as it's trying to add response data to a potentially unresolved Promise

如果在继续之前需要 responseotherResponse 的解析值,最好将所需的逻辑放在内部 then() 延续中。这是您在设置 response.otherInfo = otherResponse 时所做的,但我认为 setItemList 调用也应该在该延续内。

useEffect(() => {
  idList.forEach((id) => {
    getInfo(id)
      .then((response) => {
        getOtherInfo(id).then((otherReponse) => {
          response.otherInfo = otherResponse;
          setItemList((itemList) => [...itemList, response]);
        });
      })
      .catch((error) => console.log("Loading failed: " + error));
  });
}, []);

如果对 getOtherInfo 的请求不依赖于 getInfo 的结果,那么使用 Promise.all.

同时执行这些请求可能会有所帮助
useEffect(() => {
  idList.forEach((id) => {
    Promise.all([getInfo(id), getOtherInfo(id)])
      .then(([response, otherResponse]) => {
        response.otherInfo = otherResponse;
        setItemList((itemList) => [...itemList, response]);
      })
      .catch((error) => console.log("Loading failed: " + error));
  });
}, []);