利用作用域将lati、longi赋值为Ajax响应值调用Google Maps API是否有缺陷?
你的实现确实存在不少缺陷,主要集中在异步逻辑处理、全局变量风险、API请求格式错误以及边界情况处理等方面,咱们来逐一梳理:
1. 异步逻辑与全局变量的不可靠性
你用全局变量lati和longi存储Ajax响应的坐标,再依赖$(document).ajaxComplete()初始化地图,这里有两个核心问题:
ajaxComplete是全局事件,页面上任何一个Ajax请求完成都会触发这个回调,要是页面还有其他Ajax操作,会导致地图被意外重复初始化,覆盖正确坐标。- 虽然理论上
ajaxComplete会在你的请求完成后触发,但全局变量的赋值是在Ajax的then回调里,万一有其他请求先完成,lati和longi可能还是初始值0,直接导致地图定位到错误位置。
2. API请求URL拼接错误
你的queryURL明显存在拼接错误:
var queryURL = "https://rest.bandsintown.com/artists/" + artist + "/events?app_id=test&date=upcoming" + artist + "?app_id=test";
这里多拼接了+ artist + "?app_id=test",而且&是HTML转义字符,在JS里直接用&即可,正确的URL应该是:
var queryURL = `https://rest.bandsintown.com/artists/${artist}/events?app_id=test&date=upcoming`;
3. 硬编码数组索引导致潜在报错
你直接访问response[125].venue.name,如果返回的演出列表长度小于126,这行代码会直接抛出Cannot read properties of undefined (reading 'venue')的错误,完全没有处理边界情况。
4. 表格内容删除时机错误
$("#concertInfo").find("td").remove();写在Ajax请求外面,会在点击按钮后立即删除表格内容,但Ajax是异步的,如果请求较慢,用户会看到表格突然变空;要是请求失败,表格就会一直处于空状态,体验很差。
5. 地图坐标的逻辑错误
初始化地图时你写了lng: - longi,如果Bandsintown API返回的是正确的经度值,加负号会直接把坐标搞反(比如本来是西经120,变成东经120),这是完全不必要的逻辑错误。
6. 缺少错误处理机制
如果用户输入的艺术家不存在,或者API请求失败(比如网络问题),你的代码会直接报错,因为response[0]会是undefined,没有任何容错处理。
改进后的代码示例
我们可以把地图初始化直接放到Ajax的then回调里,去掉全局变量,同时修复上述所有问题:
$("#artistButton").on('click', function () { var artist = $("#artistSearch").val().trim(); // 修复URL拼接错误,使用模板字符串更易读 var queryURL = `https://rest.bandsintown.com/artists/${artist}/events?app_id=test&date=upcoming`; var test = $("#map").attr('data-vision'); // 保留地图显示状态切换逻辑 if (test === 'hide') { $('#map').hide(); $("#map").attr('data-vision', 'show'); } else { $('#map').show(); $("#map").attr('data-vision', 'hide'); } $.ajax({ url: queryURL, method: "GET", }).then(function (response) { console.log(response); // 先判断响应是否有数据,避免报错 if (!response || response.length === 0) { $("#artistName").html('未找到该艺术家的演出信息'); $("#artistImage").empty(); $("#venue").empty(); $("#concertInfo").find("tr:gt(0)").remove(); // 只删除数据行,保留表头 $('#map').hide(); return; } var imageURL = response[0].artist.image_url; var image = $("<img id='pictureSize'>").attr('src', imageURL); var artistName = response[0].artist.name; var today = new Date(); $("#artistName").html(artistName); $("#artistImage").html(image); // 改用第一个演出的场地,可根据需求调整,不再硬编码索引 $("#venue").html(response[0].venue.name); var lati = response[0].venue.latitude; var longi = response[0].venue.longitude; console.log('latitude ' + lati); console.log('longitude ' + longi); // 清空旧表格数据(放到成功回调里) $("#concertInfo").find("tr:gt(0)").remove(); // 遍历演出列表 for (var i = 0; i < response.length; i++) { var time = moment(response[i].datetime).format("MMM Do, YYYY hh:mm"); var concertDate = new Date(response[i].datetime); var venueName = response[i].venue.name; var city = response[i].venue.city; var region = response[i].venue.region; if (today.getTime() < concertDate.getTime()) { $("#concertInfo").append($("<tr><td>" + venueName + "</td>" + "<td>" + city + ', ' + region + "</td>" + "<td>" + time + "</td></tr>")); } } $('#map').show(); // 直接在回调里初始化地图,无需依赖全局事件和变量 initMap(lati, longi); }).fail(function(jqXHR, textStatus, errorThrown) { // 处理请求失败的情况 $("#artistName").html('请求失败,请稍后重试'); $("#artistImage").empty(); $("#venue").empty(); $("#concertInfo").find("tr:gt(0)").remove(); $('#map').hide(); console.error('API请求错误:', textStatus, errorThrown); }); }); // 把地图初始化改成接收参数的函数,彻底摆脱全局变量依赖 function initMap(lat, lng) { new google.maps.Map(document.getElementById('map'), { zoom: 10, center: { lat: parseFloat(lat), lng: parseFloat(lng) } // 确保转成数字类型 }); }
关键改进点说明
- 去掉全局变量
lati和longi,直接在Ajax回调里把坐标作为参数传给initMap,避免全局污染和异步时序问题。 - 把
ajaxComplete全局事件改成在当前请求的then回调里调用initMap,确保只有当前请求成功后才初始化地图。 - 修复API URL拼接错误,使用模板字符串提升代码可读性。
- 添加
response为空的判断以及Ajax请求失败的fail回调,增强代码健壮性。 - 调整表格内容删除时机,放到成功回调里,避免请求失败时表格空掉。
- 去掉经度前的负号,修复坐标逻辑错误。
- 替换硬编码的
response[125]为合理的索引,避免数组越界报错。
内容的提问来源于stack exchange,提问作者J.Murry
相关产品推荐
相关产品推荐

