解决JQuery/JavaScript中API调用函数外变量值为空的问题
解决异步API调用后变量无法在外部使用的问题
嘿,你这问题我太熟了——本质是AJAX请求是异步执行的!当你调用getLocation()之后,浏览器根本不会等$.getJSON请求完成,直接就往下跑switch语句了,这时候country变量还没被赋值,自然会走到default分支,显示默认文本。
给你几个实用的解决方案,按需选就行:
方案1:把逻辑直接塞进回调函数(最简单直接)
既然数据要等回调回来才有,那把所有需要用country的代码都放到回调里,确保数据到手再执行:
function getLocation() { $.getJSON('https://ipinfo.io/json', function (data) { console.log("1- Your country is " + data.country); const country = data.country; let continent; switch(country){ case "USA": case "Mexico": case "Canada": continent = "Your continent is X"; break; case "Morocco": case "Egypt": case "South Africa": continent = "Your continent is Y"; break; case "France": case "Spain": case "Germany": continent = "Your continent is Z"; break; default: continent = "this is default text"; } document.getElementById("myp").innerHTML = continent; }); } getLocation();
方案2:用Promise+async/await让代码更“同步”
如果觉得回调嵌套看着乱,可以把请求封装成Promise,用async/await让逻辑更清晰,像写同步代码一样:
function getLocation() { return new Promise((resolve, reject) => { $.getJSON('https://ipinfo.io/json', function (data) { resolve(data.country); }).fail(() => { reject(new Error('获取位置信息失败')); }); }); } async function displayContinent() { try { const country = await getLocation(); console.log("1- Your country is " + country); let continent; switch(country){ case "USA": case "Mexico": case "Canada": continent = "Your continent is X"; break; case "Morocco": case "Egypt": case "South Africa": continent = "Your continent is Y"; break; case "France": case "Spain": case "Germany": continent = "Your continent is Z"; break; default: continent = "this is default text"; } document.getElementById("myp").innerHTML = continent; } catch (err) { console.error(err); document.getElementById("myp").innerHTML = "抱歉,无法获取你的位置"; } } displayContinent();
方案3:用jQuery自带的Deferred链式调用
jQuery的AJAX方法本身就返回Deferred对象,直接用.then()链式处理结果也很方便:
function getLocation() { return $.getJSON('https://ipinfo.io/json'); } getLocation() .then(data => { console.log("1- Your country is " + data.country); const country = data.country; let continent; switch(country){ case "USA": case "Mexico": case "Canada": continent = "Your continent is X"; break; case "Morocco": case "Egypt": case "South Africa": continent = "Your continent is Y"; break; case "France": case "Spain": case "Germany": continent = "Your continent is Z"; break; default: continent = "this is default text"; } document.getElementById("myp").innerHTML = continent; }) .fail(() => { document.getElementById("myp").innerHTML = "获取位置失败"; });
核心记住一点:异步操作的结果不能在异步任务完成前使用,所有依赖这个结果的代码都要放在异步任务结束后的逻辑块里~
内容的提问来源于stack exchange,提问作者Zeusox
相关产品推荐
相关产品推荐

