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

React.js中如何在Map完成多Fetch请求后执行函数?

问题解决思路

你的问题出在两个关键地方:

  1. Promise.all 没有真正等待所有请求完成——你在urls.map里的async函数没有return fetch的Promise链,导致Promise.all等待的是一堆立刻resolved的空Promise,自然会提前触发then回调。
  2. 依赖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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:23:32