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

使用Google Map API的ElevationService时异步回调数据未定义问题求助

解决Google Maps ElevationService异步获取海拔的问题

嘿,很高兴帮你搞定这个异步小坑!你遇到的问题其实是JavaScript里非常典型的异步回调执行顺序问题——getElevationForLocations是异步方法,它不会立刻返回结果,而是等Google的API返回数据后才会触发回调函数。但你现在的getElevation函数直接返回的话,回调还没执行,自然拿不到海拔值,所以elevation就是undefined啦。

咱们可以用Promise + async/await来把异步代码改成更易读的“同步风格”,完美解决这个问题。下面是具体的修改方案:

1. 把getElevation改成返回Promise的函数

我们用Promise来包装异步的getElevationForLocations调用,让它可以被await等待:

function getElevation(location, elevator) {
  // 返回一个Promise对象
  return new Promise((resolve, reject) => {
    elevator.getElevationForLocations({
      'locations': [location]
    }, function(results, status) {
      if (status === 'OK') {
        if (results[0]) {
          // 获取到海拔后,用resolve返回结果
          resolve(results[0].elevation);
        } else {
          // 没有结果时,用reject抛出错误
          reject(new Error('未找到海拔数据'));
        }
      } else {
        // 请求失败时,抛出错误信息
        reject(new Error(`海拔请求失败: ${status}`));
      }
    });
  });
}

2. 修改addMarker为async函数,用await等待海拔结果

把addMarker变成异步函数,用await等待getElevation的Promise完成,再把数据存入数组:

async function addMarker(location, map, elevator) {
  var marker = placeMarkerAndPanTo(location, map);
  try {
    // 等待Promise完成,拿到海拔值
    var elevation = await getElevation(location, elevator);
    // 这时候海拔已经拿到了,可以安全push到数组
    markers.push({marker, elevation});
    console.log('已添加带海拔的标记:', elevation);
  } catch (error) {
    // 处理请求失败的情况,避免程序崩溃
    console.error('获取海拔失败:', error);
    // 可以选择存入null或者跳过这个标记
    markers.push({marker, elevation: null});
  }
}

3. 在点击事件中调用异步的addMarker

因为addMarker现在是async函数,我们在地图的click事件里调用时,可以加上await(如果后续有依赖这个操作的逻辑,这会很有用):

map.addListener('click', async function(e) {
  await addMarker(e.latLng, map, elevator);
});

完整修改后的代码

把所有修改整合起来,就是这样:

var markers = [];

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: {lat: -25.363882, lng: 131.044922 },
    mapTypeId: 'terrain'
  });

  var elevator = new google.maps.ElevationService;

  map.addListener('click', async function(e) {
    await addMarker(e.latLng, map, elevator);
  });
}

function getElevation(location, elevator) {
  return new Promise((resolve, reject) => {
    elevator.getElevationForLocations({
      'locations': [location]
    }, function(results, status) {
      if (status === 'OK') {
        if (results[0]) {
          resolve(results[0].elevation);
        } else {
          reject(new Error('未找到海拔数据'));
        }
      } else {
        reject(new Error(`海拔请求失败: ${status}`));
      }
    });
  });
}

function placeMarkerAndPanTo(latLng, map) {
  var marker = new google.maps.Marker({
    position: latLng,
    map: map
  });
  map.panTo(latLng);
  return marker;
}

async function addMarker(location, map, elevator) {
  var marker = placeMarkerAndPanTo(location, map);
  try {
    var elevation = await getElevation(location, elevator);
    markers.push({marker, elevation});
    console.log('已添加带海拔的标记:', elevation);
  } catch (error) {
    console.error('获取海拔失败:', error);
    markers.push({marker, elevation: null});
  }
}

这样修改后,每次点击地图时,都会先等待海拔数据返回,再把{marker, elevation}存入数组,就不会出现undefined的情况啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:27:33