2016-06-17 13 views
0

Ich habe diesen Codepegel Localweather App Ich habe zwei Funktionen erstellt.Übergabe einer Variablen von einem Ajax-Aufruf an einen anderen

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> 
 
$(document).ready(function() { 
 

 
    var city = "Newcastle"; 
 
    
 
    city = getLocation(); 
 
    //set city to location from function; 
 
    console.log ("city undefined?" +city); 
 
    //this is undefind, why? 
 
    
 
    getWeather(city).then(function(data) { 
 
    console.log(data); 
 
    var weatherType = data.weather[0].description; 
 
    var weatherId = data.weather[0].id; 
 
    var tempF = Math.round(data.main.temp); 
 
    var tempC = Math.round((tempF - 32)/1.8); 
 
    var wind = data.wind.speed; 
 
    var name = data.name; 
 
    console.log(weatherType); 
 
    $('#weather').html(weatherType); 
 
    $('#temp').html(tempC + "&#176;C"); 
 
    $('#wind').html(tempF + "&#176;F"); 
 
    $('#icon').html(weatherId); 
 
    $('#location').html(name); 
 
    
 
    }) 
 
}); 
 

 
function getLocation() { 
 
    $.getJSON('http://ipinfo.io', function(data) { 
 
    console.log("data" + data); 
 
    city = data.city; 
 
    console.log("city" + city); 
 
    return city; 
 
    }) 
 
} 
 

 
function getWeather(place) { 
 
    return $.getJSON('http://api.openweathermap.org/data/2.5/weather?q=' + place + '&units=imperial&APPID=90d625c068e3f3d7818b9e4237871e21'); 
 
} 
 
</script>

A GetWeather-Funktion, die in einen stattfindet und gibt ein Wetter Objekt für diesen Standort. Ich habe auch eine getLocation-Funktion, die ich meine Stadt basierend auf IP zurückgeben möchte (ja, ich weiß, es ist nicht genau, aber es ist, was ich verwenden möchte).

Wenn ich die Stadt fest codiere funktioniert es. Aber versuchen, die Stadt Variable aus der GetLocation-Funktion zu verwenden funktioniert nicht. Ich vermute, es ist etwas damit zu tun gewesen asynchron, aber ich würde, dass durch einen Aufruf zurück in der GetLocation-Funktion würde es die "Stadt", die "dann" in die getWeather übergeben würde zurückgeben. Oder habe ich mein Denken falsch?

+0

Was Sie in der Konsole. Anrufe protokollieren? –

+0

Sie müssen mit (verschachtelten) Callbacks arbeiten. –

+0

Sie sollten Ihre Methodenaufrufe ketten, also bei Erfolg von getLocation getWeather mit empfangenen Daten aufrufen. Sehen Sie hier, wie Ajax Callbacks funktioniert: http://api.jquery.com/jquery.getjson/ –

Antwort

1

Sie müssen mit (verschachtelten) Rückrufen arbeiten, da Sie auf die asynchronen Antworten von Ihren AJAX-Anrufen warten müssen.

Ihr Browser wartet nicht für asynchrone Funktionen zur nächsten Anweisung zu beenden und weiterlaufen, deshalb Stadt in Ihrem Code nicht definiert ist - weil in Ihrem Code getLocation nur einen Wert zurückzugibt, wenn die getJSON beendet.

Wenn Ihre Funktion so aussehen würde, würden Sie einen Rückgabewert erhalten, nur nicht den, den Sie wollen (verwenden Sie also nicht das nächste Code-Snippet, es ist nur zum Erklären da).

function getLocation() { 
    $.getJSON('http://ipinfo.io', function(data) { 
    return data.city; // this will be ignored, because the browser will jump to the next statement 
    }); 
    return "XXX"; // <- this will be returned, because the browser will not wait for async functions to finish 
} 

Im Beispiel unten haben wir eine Funktion als Parameter getLocation passieren. Der Parametername lautet callback und wir rufen diese Funktion mit dem Parameter data auf, wenn $.getJSON('http://ipinfo.io' ausgeführt wird.

Von diesem Datenparameter können wir city extrahieren und dann getWeather aufrufen.

Beachten Sie, wie getLocation keinen Wert mehr gibt, sondern übergibt er die data Parameter an die Callback (oder Sie city in getLocation und dann city an den Rückruf übergeben extrahieren könnte statt).

$(document).ready(function() { 
 

 
    getLocation(function(data) { 
 
     var city = data.city; 
 
     getWeather(city).then(function(data) { 
 
     // ... 
 
     }); 
 
    }); 
 
    }); 
 

 
    function getLocation(callback) { 
 
    $.getJSON('http://ipinfo.io', function(data) { 
 
     callback(data); 
 
    }); 
 
    } 
 

 
    function getWeather(place) { 
 
    return $.getJSON('http://api.openweathermap.org/data/2.5/weather?q=' + place + '&units=imperial&APPID=90d625c068e3f3d7818b9e4237871e21'); 
 
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> 
 
</script>

+0

Vielen Dank, aber können Sie mir den Ablauf erklären. Es mag technisch nicht korrekt sein, aber wir übergeben den größten Teil des Programms in die Get-Location-Funktion. – Greyhounddad

+0

Der Fluss erklärt sich selbst. Sie brauchen zuerst die Stadt/den Ort, bevor Sie getWeather aufrufen können. Wie gesagt, Ihr Browser wird nicht auf AJAX-Aufrufe warten, deshalb müssen Sie die Aufrufe verketten und mit Rückrufen arbeiten. Ja, getLocation ist der Ausgangspunkt Ihres Programms, also stellen Sie sicher, dass Sie den Code in Funktionen "outsourcen" (die Callback-Parameter verwenden), sonst ist es schwer zu lesen und zu verstehen, was der Code tut. Bitte markieren Sie die Antwort als akzeptiert, wenn sie Ihre Frage beantwortet. –

0

Die Stadt wäre immer noch undefiniert, da getWeather nicht auf getLocation warten und einen Wert für die Stadt vergeben wird. Sie könnten Allways

setzen
$.getJSON('http://ipinfo.io', function(data) { 
console.log("data" + data); 
city = data.city; 
console.log("city" + city); 

$.getJSON('http://api.openweathermap.org/data/2.5/weather?q=' + city + '&units=imperial&APPID=90d625c068e3f3d7818b9e4237871e21'); 
}) 

oder Sie können ein jQuery.Deferred() Objekt verwenden, um nur Wetter durchführen erhalten, wenn Stadt getan wird erhalten.

1

return city; in getLocation() liefert nur aus der anonymen Funktion function(data), die in $.getJSON übergeben wurde.Ihr getLocation nicht wirklich eine return Aussage, die diese zur Handhabung city = undefined

Ein Ansatz nutzt die getJSON Versprechen zu machen sein könnte:

getLocation().then(function (data) { 
    console.log(data); 
    getWeather(data.city).then(... 
}); 

Dann getLocation würde wie folgt aussehen:

function getLocation() { 
    return $.getJSON(... 
} 

Wie Sie aus den Antworten sehen können, gibt es viele Möglichkeiten, dies mit nested callbacks oder Promises zu umgehen.

Here you can see my codepen in action

0

Grundsätzlich Sie für die IPInfo Rückruf warten müssen, bevor Anruf openwheater, sonst Stadt nicht definiert wird, ist dies ein asynchroner Aufruf Mechanik

$(document).ready(function() { 

    getLocation().then(function(city){ 
     getWeather(city.city).then(function(data) { 
     console.log(data); 
     var weatherType = data.weather[0].description; 
     var weatherId = data.weather[0].id; 
     var tempF = Math.round(data.main.temp); 
     var tempC = Math.round((tempF - 32)/1.8); 
     var wind = data.wind.speed; 
     var name = data.name; 
     console.log(weatherType); 
     $('#weather').html(weatherType); 
     $('#temp').html(tempC + "&#176;C"); 
     $('#wind').html(tempF + "&#176;F"); 
     $('#icon').html(weatherId); 
     $('#location').html(name); 

     }, function(err){ 
     console.log("ERROR!", err); 
     }) 
    }, function(err){ 
    console.log("ERROR!", err); 
    }); 
}); 

function getLocation() { 
    return $.getJSON('http://ipinfo.io'); 
} 

function getWeather(place) { 
    return $.getJSON('http://api.openweathermap.org/data/2.5/weather?q=' + place + '&units=imperial&APPID=90d625c068e3f3d7818b9e4237871e21'); 
} 
1

Wenn Sie Kette wollen ruft AJAX, Sie muss den nächsten AJAX-Anruf innerhalb des Rückrufs des vorherigen festlegen. Auf diese Weise wird der nächste AJAX-Anruf nur gesendet, nachdem der vorherige beendet wurde.

Diese Antwort ist eine kleine Variante, die IP-Adresse zum Abrufen von Breiten-/Längengrad (anstelle von Stadt) verwendet & dann verwendet, dass für das Wetter.

http://codepen.io/anon/pen/ZOpEBQ

var ip = '8.8.8.8'; 
 

 
$.get('https://ipapi.co/'+ip+'/latlong/', function(data){ 
 
    
 
    data = data.split(','); 
 
    console.log(data); 
 
    
 
    $.get('http://api.openweathermap.org/data/2.5/weather?lat='+data[0]+'&lon='+data[1]+'&units=imperial&APPID=90d625c068e3f3d7818b9e4237871e21', function(data1) { 
 
    
 
    // Should print the weather 
 
    console.log(data1); 
 
    
 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Verwandte Themen