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

在React useEffect中使用map结合Axios为何返回Promise数组而非目标对象数组?

问题原因分析

你遇到的这个问题其实很常见:因为async函数本身的返回值就是一个Promise,当你把async function作为map的回调函数时,map遍历后得到的数组里每个元素都是Promise实例,而不是你期望的处理后的资产对象——这就是控制台打印出一堆Promise的核心原因。

解决方案

要解决这个问题,你需要用Promise.all()来等待所有异步请求完成,拿到真正的结果数组后再更新状态。另外要注意:useEffect的回调函数不能直接设为async,所以我们可以在它内部定义一个异步函数并调用。

修改后的代码如下:

useEffect(() => {
  // 定义内部异步函数,处理所有资产请求逻辑
  const fetchAndProcessAssets = async () => {
    // 用Promise.all等待所有异步请求完成,拿到最终的结果数组
    const newAssetArray = await Promise.all(
      dummyAssets.map(async (asset) => {
        try {
          const response = await axios.get(currrentPrice(asset.asset_id));
          const cp = response.data.market_data.current_price.eur;
          const value = Number(cp) * Number(asset.amount);
          // 返回添加了value字段的新资产对象
          return { ...asset, value: +value };
        } catch (error) {
          console.log(error.response.data.error);
          // 这里可以自定义请求失败时的返回值,比如标记错误状态或保留原资产
          return { ...asset, value: null, hasError: true };
        }
      })
    );
    setAssets(newAssetArray);
    console.log(newAssetArray);
  };

  // 调用内部异步函数
  fetchAndProcessAssets();
}, [dummyAssets]);
关键改动说明
  • 用Promise.all()包裹map的结果,通过await等待所有请求完成,就能得到包含处理后对象的真实数组
  • 将异步逻辑封装在内部函数中,避免直接把useEffect回调设为async(这会导致React无法正确清理副作用)
  • 把原来的.then/.catch换成try/catch写法,逻辑更直观,还能在请求失败时统一处理返回值(比如给失败的资产标记错误状态)

如果想过滤掉请求失败的资产,可以在Promise.all之后加一步处理:

const validAssets = newAssetArray.filter(item => !item.hasError);
setAssets(validAssets);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 01:57:50