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

同期スコープと非同期コードが混乱する可能性があります。 * working *コードがあるので、これは完全に重複しているわけではありません。しかし、あなたが探している答えはおそらくここにあります:https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – David

+1

'getCurrentPosition()' is非同期。したがって、データが受信されるまでアクセスすることはできません。それはまだ届いていないピザを食べようとするのと同じです – charlietfl

答えて

1

スクリプトにはいくつか問題があります。すべての

まず、navigator.geolocation.getCurrentPosition(...)戻りundefinedは、あなたが実際にページloadイベントにイベントハンドラをアタッチしていない、とaddEventListener()への呼び出しは、何もせず、静かに失敗しました。

第2に、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

関連する問題