JavaScript全局变量code在函数外无法取值的技术求助
异步AJAX导致全局变量
code外部调用返回undefined的解决方法 问题核心原因
你的问题本质是AJAX异步执行的时序问题:
addCountryBorder里的AJAX请求是异步操作,函数执行完毕后,请求还在后台处理,此时你立刻调用的countryInfo拿不到还没被赋值的code。- 页面初始化时的
console.log(code)会直接执行,这时候下拉框的change事件都没触发,AJAX根本没启动,自然返回undefined。 - 你在success回调里写的
return code;毫无作用——这个return是给AJAX的回调函数的,不是给addCountryBorder函数的,外部根本拿不到这个返回值。
解决方案(推荐用Promise+async/await,避免全局变量依赖)
1. 修改addCountryBorder,让它返回Promise
把异步操作包装成Promise,方便后续等待执行完成:
function addCountryBorder(countryName) { return new Promise((resolve, reject) => { $.ajax({ url: "assets/geojson/countryBorders.geo.json", type: "GET", dataType: "json", success: function(result) { let features = result["features"]; let countryFeature = findFeatureFromName(countryName); if (!countryFeature) { reject("未找到对应国家数据"); return; } // 没必要用JSON.stringify,直接存原始的iso_a2值即可 const code = countryFeature.properties.iso_a2; // 处理地图边界逻辑 if (border) { map.removeLayer(border); } border = new L.geoJSON(countryFeature["geometry"], { style: { color: "#006600", } }).addTo(map); map.panTo(border.getBounds().getCenter()); map.fitBounds(border.getBounds()); // 把获取到的code传递出去 resolve(code); }, error: function(jqXHR, textStatus, errorThrown) { console.log(errorThrown); reject(errorThrown); } }); }); }
2. 修改下拉框change事件,等待异步操作完成后调用countryInfo
用async/await等待addCountryBorder执行完毕,拿到code后再传给countryInfo:
$("#innerSelect").on("change", async () => { const selectedCountry = $("#innerSelect").val(); try { // 等待addCountryBorder完成,拿到国家代码 const code = await addCountryBorder(selectedCountry); // 直接把code传给countryInfo countryInfo(code); // 其他坐标请求逻辑保持不变 $.ajax({ url: "libs/php/getCoordsFromCountryName.php", type: "GET", dataType: "json", data: { countryName: selectedCountry, }, success: function(result) { if (result.status.name == "ok") { map.panTo(new L.LatLng(result["data"][0]["geometry"]["lat"], result["data"][0]["geometry"]["lng"])) } }, error: function(jqXHR, textStatus, errorThrown) { console.log(errorThrown); } }); } catch (err) { console.error("操作失败:", err); } });
3. 修改countryInfo,通过参数接收code(彻底摆脱全局变量)
function countryInfo(code) { // 先判断code是否有效 if (!code) { console.error("未传入有效的国家代码"); return; } $.ajax({ url: "assets/php/countryInfo.php", type: 'POST', dataType: 'json', data: { country: code, }, success: function(result) { if (result.status.name == "ok") { coords.push({currencyCode: result.data[0].currencyCode}); let formattedPopulation = result['data'][0]['population'].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); let formattedArea = Math.round(result['data'][0]['areaInSqKm']).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); $('#continent').html(result['data'][0]['continentName']); $('#capital').html(result['data'][0]['capital']); $('#countryName').html(result['data'][0]['countryName']); $('#population').html(formattedPopulation); $('#currencyCode').html(result['data'][0]['currencyCode']); $('#area').html(formattedArea); currencyConverter(); } }, error: function(jqXHR, textStatus, errorThrown) { console.log(jqXHR) console.log(textStatus) console.log(errorThrown) } }); }
简化方案(适合快速修复)
如果不想用Promise,也可以直接在addCountryBorder的success回调里调用countryInfo:
// 修改addCountryBorder的success部分 success: function(result) { // ...省略前面的逻辑... const code = countryFeature.properties.iso_a2; // ...省略地图边界逻辑... // 直接在这里调用countryInfo,把code传过去 countryInfo(code); } // 修改change事件,去掉单独调用countryInfo的代码 $("#innerSelect").on("change", () => { const selectedCountry = $("#innerSelect").val(); addCountryBorder(selectedCountry); // 其他AJAX请求保持不变 });
内容的提问来源于stack exchange,提问作者javascript_bewildered934
相关产品推荐
相关产品推荐

