2017-06-03 143 views
0

我正在做一个家庭作业项目,使用API​​来显示天气。最初,我在脚本的顶部声明了变量“latty”和“lonny”,在主函数范围内其他所有变量都在内部,随后使用navigator.geolocation将它们设置为经度和纬度。将它们设置为坐标后,我尝试将它们用作发送到API的URL行的一部分,但latty和lonny的值从未结转。我认为在父函数中声明它们可以让它们在随后的嵌套函数中使用。由于地理位置要求,以获得坐标的功能,我结束了在为了能够使用它检索值不必巢为getPosition()函数内的整个脚本:从功能范围变量获取值

this.addEventListener("load", navigator.geolocation.getCurrentPosition(getPosition)); 

function getPosition(position) { 
    var latty = position.coords.latitude; 
    var lonny = position.coords.longitude; 
    var url = "https://api.darksky.net/forecast/"; 
    var apiKey = '5a4ae697ea6b02e5a4ae697ea6b02e/'; 

weatherAjax(); 

function weatherAjax(){ 
$.ajax({ 
    url: url + apiKey + latty + "," + lonny + degreeType, 
    dataType: 'jsonp', 
    success: function(data) { 
    $("#weatherID").html("<h1>" + Math.round(data.currently.temperature) + degreeSymbol + data.currently.summary + "</h1>"); 
    } 
}); 
} 

有没有更好的方法来做到这一点,而不是在getPosition()中嵌套一切?看起来很奇怪,我无法从地理位置获取信息,将这些坐标设置为变量,并将它们调用到另一个函数中。我无法弄清楚如何返回这些信息,我也不会在这里与你分享这个混乱,因为这很糟糕。

我理解作用域的基本思想是:只能访问嵌套顺序中“更高”的变量。同级或子级功能不会“共享”变量访问。它是否正确?这可以改善吗?

+0

这听起来像你可能会混淆函数范围与同步和异步代码。由于你有*工作*代码,这不完全是重复的。但你正在寻找的答案可能在这里:https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – David

+1

'getCurrentPosition()'是异步。因此,只有收到数据后才能访问数据。这与尝试吃尚未交付的披萨相同 – charlietfl

回答

1

您的脚本存在一些问题。

首先,navigator.geolocation.getCurrentPosition(...)回报undefined,这样你就不会真正连接的事件处理程序load页面事件,并addEventListener()该调用什么都不做,静静地失败。

其次,还有一种更好的组织脚本的方法,以便您不必将脚本嵌套在getPosition()回调中。 使用功能参数

navigator.geolocation.getCurrentPosition(getPosition); 

function getPosition(position) { 
    var latty = position.coords.latitude; 
    var lonny = position.coords.longitude; 
    var url = "https://api.darksky.net/forecast/"; 
    var apiKey = '5a4ae697ea6b02e5a4ae697ea6b02e/'; 

    weatherAjax(latty, lonny, url, apiKey); 
} 

function weatherAjax(latty, lonny, url, apiKey) { 
    $.ajax({ 
    url: url + apiKey + latty + "," + lonny + degreeType, 
    dataType: 'jsonp', 
    success: function (data) { 
     $("#weatherID").html("<h1>" + Math.round(data.currently.temperature) + degreeSymbol + data.currently.summary + "</h1>"); 
    } 
    }); 
} 

所以,最后,如果你想这实际上在页面加载后运行,扔了这一切变成一个匿名回调load

window.addEventListener('load', function() { 
    // everything above goes in here 
}); 

总之,你得到这个:

window.addEventListener('load', function() { 

    navigator.geolocation.getCurrentPosition(getPosition); 

    function getPosition(position) { 
    var latty = position.coords.latitude; 
    var lonny = position.coords.longitude; 
    var url = "https://api.darksky.net/forecast/"; 
    var apiKey = '5a4ae697ea6b02e5a4ae697ea6b02e/'; 

    weatherAjax(latty, lonny, url, apiKey); 
    } 

    function weatherAjax(latty, lonny, url, apiKey) { 
    $.ajax({ 
     url: url + apiKey + latty + "," + lonny + degreeType, 
     dataType: 'jsonp', 
     success: function (data) { 
     $("#weatherID").html("<h1>" + Math.round(data.currently.temperature) + degreeSymbol + data.currently.summary + "</h1>"); 
     } 
    }); 
    } 

}); 
+0

感谢您指出。我曾使用过setTimeout,但没有意识到它可能在某个时间点实际上需要超过2秒的延迟,因为它从来没有失败过。根据你的回答我改变了我的代码。 – Ozan