2017-06-03 19 views
0

Ich arbeite an einem Hausaufgabenprojekt, um eine API zur Anzeige des Wetters zu verwenden. Ursprünglich habe ich die Variablen "latty" und "lonny" am Anfang meines Skripts deklariert, im Hauptfunktionsbereich war alles andere drin, und später wurden sie mit Hilfe von navigator.geolocation auf den Längen- und Breitengrad gesetzt. Nachdem ich sie auf die Koordinaten gesetzt hatte, versuchte ich dann, sie als Teil der URL-Zeile zu verwenden, die an die API gesendet wurde, aber die Werte für Latty und Lonny wurden nie übertragen. Ich dachte, sie in der Elternfunktion zu deklarieren würde ihnen erlauben, in nachfolgenden verschachtelten Funktionen verwendet werden. Da die Entfernung zu kennen, eine Funktion benötigt, um Koordinaten zu erhalten, landete ich in der getPosition() Funktion das gesamte Skript zu Nest mit bis, um die Werte zu verwenden, um der Lage sein, die es abruft:Abrufen von Werten aus Variablen mit Funktionsumfang

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>"); 
    } 
}); 
} 

Gibt es eine bessere Möglichkeit, dies zu tun, ohne alles in getPosition() zu verschachteln? Es ist merkwürdig, dass ich keine Informationen aus der Geolokalisierung bekomme, diese Koordinaten auf eine Variable setze und sie in eine andere Funktion aufrufe. Ich konnte mir auch nicht vorstellen, wie ich diese Informationen zurückgeben sollte, und ich werde dieses Chaos hier nicht mit dir teilen, weil es schrecklich war.

Ich verstehe die Grundidee von Scope als: Sie können nur auf Variablen zugreifen, die in der Verschachtelungsreihenfolge "höher" sind. Geschwister- oder untergeordnete Funktionen teilen den Variablenzugriff nicht mit. Ist das richtig? Kann das verbessert werden?

+0

Es klingt wie Sie können Funktionsumfang mit synchronen und asynchronen Code verwirren. Da Sie einen * Arbeits * -Code haben, ist dies kein vollständiges Duplikat. Aber die Antworten, die Sie suchen, sind wahrscheinlich hier: https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – David

+1

'getCurrentPosition()' ist asynchron. Sie können also erst auf die Daten zugreifen, wenn sie empfangen wurden. Es ist das gleiche wie zu versuchen, eine Pizza zu essen, die noch nicht geliefert wurde – charlietfl

Antwort

1

Es gibt ein paar Probleme mit Ihrem Skript.

Zunächst einmal navigator.geolocation.getCurrentPosition(...) kehrt undefined, so dass Sie nicht wirklich einen Event-Handler an die load Veranstaltungsseite angebracht, und das Gespräch addEventListener() tut nichts und nicht still.

Zweitens gibt es eine bessere Möglichkeit, das Skript zu organisieren, so dass Sie Ihr Skript nicht in den getPosition() Callback verschachteln müssen. Verwenden Funktionsparameter:

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>"); 
    } 
    }); 
} 

So, endlich, wenn Sie dies wünschen, nachdem die Seite geladen wird tatsächlich laufen, zu load all das in einem anonymen Callback werfen:

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

Alle zusammen, Sie erhalten dies:

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

Danke für das Aufzeigen. Ich hatte setTimeout benutzt, ohne zu merken, dass es irgendwann mehr als 2s Verzögerung brauchte, da es nie versäumt hatte. Ich habe meinen Code entsprechend Ihrer Antwort geändert. – Ozan

Verwandte Themen