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

ReactJs中useEffect内调用API出现异步顺序异常及返回值undefined问题

问题根因
  • 调用逻辑未加等待控制:useEffect中直接调用api1、api2两个异步函数时没有加await,async函数执行到内部await语句时会立即返回pending状态的Promise,主线程不会阻塞就会直接执行下一行的api2(),自然就出现了api1没走完就触发api2的情况。
  • axios参数配置错误:axios.put/axios.post的第四个参数不生效,withCredentials属于请求配置项,必须放在第三个参数的config对象中,配置错误可能导致请求鉴权失败、跨域拦截,触发静默报错,最终返回结果为undefined。
  • 异步写法混用导致逻辑不可控:同时使用await和.then链式调用,虽然语法上没有报错,但没有显式返回请求结果,如果你在外部接收api1的返回值自然只能拿到undefined。
  • 全局属性覆盖问题:直接修改axios.myHashData这个全局属性,两个异步请求并行执行时会互相覆盖这个值,可能导致其中一个请求的签名校验失败,返回异常。
修复方案

场景1:需要api1执行完成后再调用api2(串行执行)

useEffect(() => {
  // 自执行async函数处理异步逻辑
  (async () => {
    await api1();
    await api2();
  })();
}, []);

const api1 = async () => {
  try {
    const requestModel = JSON.stringify({ UserId: userid, MenuName: menuname });
    const requestBody = security.encrypt(requestModel);
    // 单独存储签名,不要直接修改axios全局属性,避免并行请求互相覆盖
    const hashData = security.computedHmac256(requestBody);
    const config = { 
      headers: { 
        'Content-Type': 'application/json', 
        'Access-Control-Allow-Origin': '*',
        // 签名可放到自定义请求头中,按需替换成你们约定的头字段即可
        'X-Hash-Data': hashData
      },
      // withCredentials统一放到config配置项中
      withCredentials: true
    }
    // 去掉冗余的.then,直接用await拿响应结果
    const response = await axios.put(axios.controllername + 'methodname', requestBody, config);
    if (response.status === 200) {
      //setapidata(response.data);
      // 需要返回结果就显式return
      return response.data;
    }
  } catch (error) {
    console.error('api1请求错误:', error);
  }
}

const api2 = async () => {
  try {
    const requestModel = JSON.stringify({ UserID: userid });
    const requestBody = security.encrypt(requestModel);
    const hashData = security.computedHmac256(requestBody);
    const config = { 
      headers: { 
        'Content-Type': 'application/json', 
        'Access-Control-Allow-Origin': '*',
        'X-Hash-Data': hashData
      },
      withCredentials: true
    }
    const response = await axios.post(axios.controllername + 'methodname', requestBody, config);
    if (response.status === 200) {
      setapidata(response.data);
      GetApis();
      return response.data;
    }
  } catch (error) {
    console.error('api2请求错误:', error);
  }
}

场景2:两个接口互不依赖,可并行执行,需等待所有请求完成后再处理后续逻辑

替换useEffect内的逻辑即可:

useEffect(() => {
  (async () => {
    const [api1Res, api2Res] = await Promise.all([api1(), api2()]);
    // 后续统一处理两个接口的返回结果
  })();
}, []);

如果业务要求必须把签名挂载到axios实例上,不要直接修改全局axios,建议给每个请求单独创建axios实例,避免多个请求互相覆盖配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 07:12:03