2017-06-03 136 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