使用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
相关产品推荐
相关产品推荐

