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

JavaScript全局变量code在函数外无法取值的技术求助

异步AJAX导致全局变量code外部调用返回undefined的解决方法

问题核心原因

你的问题本质是AJAX异步执行的时序问题:

  1. addCountryBorder里的AJAX请求是异步操作,函数执行完毕后,请求还在后台处理,此时你立刻调用的countryInfo拿不到还没被赋值的code。
  2. 页面初始化时的console.log(code)会直接执行,这时候下拉框的change事件都没触发,AJAX根本没启动,自然返回undefined。
  3. 你在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 13:55:24