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

React+TypeScript中如何正确访问async函数返回的异步数据

问题根因

两个核心问题导致拿不到正确数据、触发类型报错:

  • 所有async标记的函数返回值永远是Promise对象,调用时如果不通过await等待Promise状态变更,拿到的永远是pending状态的Promise实例,不可能直接拿到内部resolve的实际数据
  • 类型定义和接口实际返回结构不匹配:接口实际返回的是WeatherAPI结构的数组,但给请求方法、axios泛型定义的返回类型是单个WeatherAPI对象,TS按照定义的类型做校验时,自然会认为单个对象上不存在数组下标0属性,抛出类型错误
修复步骤
  • 第一步:对齐类型定义,把所有涉及到接口返回值的泛型、返回值类型,从单个对象改为数组类型
  • 第二步:调用getLatLong方法时加上await关键字,等待异步请求返回后再拿到实际数据做后续操作
修复后完整代码
// 单条位置数据的接口定义保持不变
export interface WeatherAPI {
    country: string,
    lat: number,
    local_names: object,
    lon: number,
    name: string,
    state: string
}

async getLatLong(location: string): Promise<WeatherAPI[]> {
    // axios.get的泛型要和response.data的实际结构对齐,这里传数组类型
    const response = await axios.get<WeatherAPI[]>(`${this.latLongUrl}q=${location}`)
    return response.data;
}

async getWeather(location: string) {
    // 加await等待异步请求完成,拿到实际的数组数据
    const latLong = await this.getLatLong(location);
    // 此时latLong的类型被正确推导为WeatherAPI[],下标访问不会触发类型报错
    console.log(latLong[0]);
}
React场景额外注意

如果是在函数组件的useEffect中触发上述请求,不能直接给useEffect的回调函数加async标记,需要在回调内部定义异步函数再执行,示例代码:

useEffect(() => {
  const loadWeatherData = async () => {
    const latLongList = await getLatLong('北京');
    // 拿到数据后执行state更新等操作
  };
  loadWeatherData();
}, []);
规则总结
  • 所有async函数的返回值都会被JS自动包装为Promise,必须通过await或者.then()链式调用才能拿到内部返回的实际数据
  • 给axios写泛型、给异步方法写返回值类型时,必须1:1对齐接口实际返回的结构:返回数组就写接口名[],返回带分页、外层包裹字段的结构就补充定义对应的外层类型,不要直接用单条数据的类型代替整个返回结构
  • 只要TS报类型属性不存在的错误,先检查定义的类型和实际运行时的数据结构是不是一致,不要用any强行绕过,避免后续出现更多隐性bug

内容的提问来源于stack exchange,提问作者Arak Tai'Roth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:36:19