React中如何合并多个异步API响应并存入数组?
异步API调用合并结果的问题解决
问题场景
我正在进行API调用获取用户ID,再根据这些ID发起另一轮API调用,尝试合并响应结果,但遇到了异步问题。代码如下:
const SearchUser = async () => { try { const response = await getSearchUsers(); const ids = response.data?.map((user) => user.userId); await ids.forEach(async (id) => { const result = await getUserInfo(id); setUsers(...result); // combine result in one state }); } catch (error) { setSearching(false); } }; useEffect(() => { SearchUser(); console.log('Users', Users); // this is empty and runs even before calling api }, []);
问题分析
forEach不支持异步等待:await ids.forEach(...)无效,因为forEach本身不返回Promise,外层await无法等待内部所有异步请求完成。setUsers写法错误:setUsers(...result)会拆分result的元素作为单独参数传递,无法正确合并数组;且每次调用都会覆盖之前的状态,无法实现累加。- 状态日志时机错误:组件初始渲染时
Users为空,SearchUser是异步函数,不会阻塞useEffect执行,导致console.log先输出空值。
修复方案
1. 用Promise.all批量处理异步请求
遍历ID列表生成请求Promise,通过Promise.all等待所有请求完成,一次性获取所有用户信息结果。
2. 正确更新状态
拿到所有结果后,直接将数组赋值给状态;如果需要累加历史数据,使用函数式更新避免状态覆盖。
3. 监听状态变化打印日志
通过额外的useEffect监听Users状态,当状态更新时再执行打印操作。
修正后的代码
const SearchUser = async () => { try { const response = await getSearchUsers(); // 处理空数据,确保ids是数组 const ids = response.data?.map((user) => user.userId) || []; // 批量发起请求并等待所有结果 const userInfos = await Promise.all( ids.map(id => getUserInfo(id)) ); // 直接设置所有用户信息到状态 setUsers(userInfos); // 如果需要累加历史用户,改用: // setUsers(prev => [...prev, ...userInfos]); setSearching(false); } catch (error) { console.error('获取用户信息失败:', error); setSearching(false); } }; useEffect(() => { SearchUser(); }, []); // 监听Users状态变化,更新时打印 useEffect(() => { console.log('Users', Users); }, [Users]);
额外说明
- 如果需要允许部分请求失败,可替换
Promise.all为Promise.allSettled,之后遍历结果过滤成功的响应。 - 始终处理
response.data为空的情况,避免后续数组操作报错。
内容的提问来源于stack exchange,提问作者Maheen Nasir
相关产品推荐
相关产品推荐

