React.js中如何在Map完成多Fetch请求后执行函数?
问题解决思路
你的问题出在两个关键地方:
Promise.all没有真正等待所有请求完成——你在urls.map里的async函数没有return fetch的Promise链,导致Promise.all等待的是一堆立刻resolved的空Promise,自然会提前触发then回调。- 依赖React state(
thisCall)收集响应是错误的——state更新是异步批量执行的,就算请求都完成了,thisCall的更新也还没生效,而且多次调用setThisCall会触发多次状态合并,根本没法保证最终的thisCall是完整的。
正确的实现方式
直接在Promise.all中收集所有响应数据,等全部请求完成后,一次性更新records即可,完全不需要中间的thisCall状态:
// 先处理每个请求,返回包含source和response的对象 const responses = await Promise.all( urls.map(async (url) => { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: messageBody }); const data = await response.json(); // 返回需要的结构,让Promise.all收集成数组 return { source: source, // 确保每个url对应的source正确,若source与url一一对应,可结合索引配对 response: data.body }; }) ); // 所有请求完成后,一次性更新records setRecords(prev => [ { call: requestText, responses: responses // 直接用收集到的完整响应数组 }, ...prev ]);
关键修正点说明
- 让
Promise.all真正等待请求:每个map里的async函数必须return请求处理后的结果(不管用await还是then链),这样Promise.all才能追踪所有请求的完成状态。 - 避免依赖中间state:直接在内存中收集响应数组,等所有请求完成后再一次性更新state,既保证数据完整,也减少不必要的state更新次数。
- 修正拼写错误:你原来的代码里把
responses写成了reponses,这个也要改掉,否则records里的字段会不符合预期。
如果你的source是和每个url一一对应的(比如urls数组和sources数组索引配对),可以调整map写法来获取对应source:
// 假设存在与urls索引对应的sources数组 const responses = await Promise.all( urls.map(async (url, index) => { const response = await fetch(url, { /* 请求配置 */ }); const data = await response.json(); return { source: sources[index], response: data.body }; }) );
内容的提问来源于stack exchange,提问作者vallycat734
相关产品推荐
相关产品推荐

