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

ReactJS问题:非Promise场景下无法从函数中获取数据

解决异步回调中无法获取值的问题

你遇到的是异步操作的经典陷阱!咱们先把问题拆解清楚:

service.getDistanceMatrix是一个异步函数——它不会立刻执行完内部的回调逻辑,而是先向服务端发送请求,等拿到响应后才会调用你传入的回调函数。但你写在函数外面的console.dir(location)和console.dir(location.distFinal)是同步执行的,这时候回调里的代码还没跑,distFinal自然还没被赋值,所以打印出来是undefined。

至于为什么console.dir(location)能看到distFinal属性?这是浏览器控制台的惰性求值特性:当你点开控制台里的对象时,回调已经执行完毕,对象已经被更新了,但在你执行console.dir(location)的那一刻,这个属性其实还不存在。

解决方案

所有依赖distance的逻辑,必须等异步操作完成后再执行,这里给你几种常用的处理方式:

1. 直接把逻辑放到回调函数内部(最简单直接)

把需要使用distance的代码,全部写到回调里status == 'OK'的分支中:

service.getDistanceMatrix({ 
  origins: ["Waterloo ON"], 
  destinations: destination, 
  travelMode: 'DRIVING', 
  avoidHighways: false, 
  avoidTolls: false 
}, function(response, status){
  if (status == 'OK') {
    var origins = response.originAddresses;
    var destinations = response.destinationAddresses;
    for (var i = 0; i < origins.length; i++) {
      var results = response.rows[i].elements;
      for (var j = 0; j < results.length; j++) {
        var element = results[j];
        var distance = element.distance.text;
        var from = origins[i];
        var to = destinations[j];
        
        location.distFinal = distance;
        location.setState({ dist: distance });
        
        // 在这里使用distance,或者调用处理它的函数
        console.dir(location.distFinal); // 这里能拿到正确的值
        processDistance(distance, from, to); // 比如调用专门的处理函数
      }
    }
  }
})

// 专门处理distance的函数
function processDistance(distance, from, to) {
  // 所有需要用distance的逻辑都写在这里
  console.log(`从${from}到${to}的距离是${distance}`);
}

2. 用Promise+async/await改写(更现代的写法)

如果你的环境支持ES6+,可以把回调式的函数包装成Promise,用async/await让代码看起来像同步逻辑:

// 先把getDistanceMatrix包装成Promise
function fetchDistanceMatrix(options) {
  return new Promise((resolve, reject) => {
    service.getDistanceMatrix(options, (response, status) => {
      if (status === 'OK') {
        resolve(response);
      } else {
        reject(new Error(`请求失败:${status}`));
      }
    });
  });
}

// 用async/await调用
async function getDistance() {
  try {
    const response = await fetchDistanceMatrix({
      origins: ["Waterloo ON"], 
      destinations: destination, 
      travelMode: 'DRIVING', 
      avoidHighways: false, 
      avoidTolls: false 
    });
    
    // 提取distance并处理
    const origins = response.originAddresses;
    const destinations = response.destinationAddresses;
    for (let i = 0; i < origins.length; i++) {
      const results = response.rows[i].elements;
      for (let j = 0; j < results.length; j++) {
        const element = results[j];
        const distance = element.distance.text;
        
        location.distFinal = distance;
        location.setState({ dist: distance });
        
        // 在这里使用distance
        console.dir(location.distFinal);
      }
    }
  } catch (err) {
    console.error('获取距离失败:', err);
  }
}

// 调用函数
getDistance();

额外注意:React setState的异步性

如果你用的是React,setState本身也是异步的,所以如果在setState后立刻打印location.state.dist,也可能拿不到最新值。这时候可以用setState的回调函数:

location.setState({ dist: distance }, () => {
  // 这个回调会在state更新完成后执行
  console.log('更新后的距离:', location.state.dist);
});

核心总结:异步操作的代码不会按顺序同步执行,所有依赖异步结果的逻辑,必须放在回调、Promise的then或者await之后。

内容的提问来源于stack exchange,提问作者its.david

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:42:51