JavaScript异步转同步实现:新手求教谷歌地图API代码改造
把依赖异步操作的代码改成“同步风格”执行(附Angular示例)
嘿,作为刚接触JS异步的新手,你遇到的这个问题简直太典型了——很多人刚上手异步的时候,都想把这种有先后依赖的操作改成像同步代码那样线性执行,毕竟逻辑顺下来更省心。先给你提个醒:别用真正的同步请求(比如阻塞主线程的XHR),那会让页面直接卡死,用户体验拉胯到爆。咱们用现代JS的async/await语法糖,既能写出像同步一样的线性代码,又能保持异步的非阻塞特性,完美解决你的需求!
第一步:把谷歌地图Geocoder的回调转成Promise
谷歌地图的地理编码API是回调式的,没法直接用await,所以咱们先把它封装成返回Promise的函数:
function getCoordinates(address) { return new Promise((resolve, reject) => { const geocoder = new google.maps.Geocoder(); geocoder.geocode({ address: address }, (results, status) => { if (status === google.maps.GeocoderStatus.OK) { // 提取经纬度 const lat = results[0].geometry.location.lat(); const lng = results[0].geometry.location.lng(); resolve({ lat, lng }); } else { // 处理编码失败的情况 reject(new Error(`地理编码失败:${status}`)); } }); }); }
第二步:改造你的$scope.findLocations函数
AngularJS的$http本身就返回Promise,所以直接结合async/await就能写出“同步风格”的代码:
$scope.findLocations = async function () { try { // 1. 先等谷歌地图返回经纬度 const userAddress = $scope.inputAddress; // 假设你的地址输入框绑定了这个变量 const coordinates = await getCoordinates(userAddress); // 2. 拿到经纬度后,再调用服务器接口 const serverResponse = await $http.get('/your-server-api/locations', { params: { latitude: coordinates.lat, longitude: coordinates.lng } }); // 3. 处理服务器返回的附近地点数据 $scope.nearbyLocations = serverResponse.data; } catch (error) { // 统一处理所有错误:比如地址无效、网络问题、服务器报错 console.error('获取附近地点出错:', error); $scope.errorTip = '哎呀,获取失败了,请检查地址是否正确,或者稍后再试~'; } };
关键知识点说明
async/await只是Promise的语法糖,本质还是异步执行,不会阻塞浏览器主线程,这比老式的同步请求友好太多。- 必须用
try/catch包裹await的代码块,因为任何一个Promise失败(reject)都会抛出异常,得手动捕获处理。 - 要确保谷歌地图的脚本已经加载完成再调用
getCoordinates,不然会报google is not defined的错误,可以在地图加载完成后再初始化你的Angular控制器。
备选方案:Promise链式调用
如果你不想用async/await,也可以用Promise的链式写法,逻辑是一样的,只是写法稍显嵌套:
$scope.findLocations = function () { const userAddress = $scope.inputAddress; getCoordinates(userAddress) .then(coordinates => { return $http.get('/your-server-api/locations', { params: coordinates }); }) .then(response => { $scope.nearbyLocations = response.data; }) .catch(error => { console.error('出错了:', error); $scope.errorTip = '获取附近地点失败,请重试'; }); };
绝对要避免的坑
别用同步XMLHttpRequest(比如xhr.open('GET', url, false)),这种写法会让浏览器完全卡住,直到请求完成,用户连页面都动不了,现代浏览器甚至在很多场景下会直接禁止这种同步请求。
内容的提问来源于stack exchange,提问作者Denys Wylliam
相关产品推荐
相关产品推荐

