So I’m trying to run a function in JavaScript but I need all the other functions to run and finish before that one starts. Here’s the code (sorry, I know it’s long but its the only way I can illustrate what’s happening):
getWeather();
getAverage();
function getWeather() {
$.getJSON("http://where.yahooapis.com/geocode?q=" + lat + ",+" + lon + "&gflags=R&flags=J", function(data){
zipCode = data.ResultSet.Results[0].postal;
zipCode = zipCode.substring(0,5);
WOEID = data.ResultSet.Results[0].woeid;
getYahooWeather(WOEID);
getWeatherbug(zipCode);
getWeatherUnderground(zipCode);
getWorldWeather(zipCode);
});
}
function getYahooWeather(x) {
var query = escape('select item from weather.forecast where woeid="'+x+'"');
var url = "http://query.yahooapis.com/v1/public/yql?q=" + query + "&format=json";
$.getJSON(url, function(data2){
yahooTemp = data2.query.results.channel.item.condition.temp;
$("#yahoo-weather p").replaceWith("<p>Weather from Yahoo! powered by The Weather Channel = "+yahooTemp+"°F</p>");
});
}
function getWeatherbug(x) {
var url = "http://i.wxbug.net/REST/Direct/GetObs.ashx?api_key="+ weatherbugAPI + "&zip="+x+"&ht=t&ic=1&f=?";
console.log(url);
$.ajax({
url: url,
dataType: "jsonp",
success: function(data3) {
//console.log(data3.temperature);
wbTemp = data3.temperature;
$("#wb-weather p").replaceWith("<p>Weather from WeatherBug = "+wbTemp+"°F</p>");
}
});
}
function getWeatherUnderground(x) {
$.ajax({
url: "http://api.wunderground.com/api/b87325296cd69fa8/geolookup/conditions/q/IA/"+x+".json",
dataType: "jsonp",
success: function(parsed_json) {
var location = parsed_json['location']['city'];
wuTemp = parsed_json['current_observation']['temp_f'];
$("#wu-weather p").replaceWith("<p>Weather from Weather Underground = "+wuTemp+"°F</p>");
}
});
}
function getWorldWeather(x) {
var url = "http://free.worldweatheronline.com/feed/weather.ashx?key="+wwKey+"&q="+x+"&fx=no&format=json";
$.ajax({
url: url,
dataType: "jsonp",
success: function(data6) {
wwTemp = data6.data.current_condition[0].temp_F;
$("#ww-weather p").replaceWith("<p>Weather from World Weather Online = "+wwTemp+"°F</p>");
}
});
}
function getAverage() {
avTemp = wbTemp + wwTemp + yahooTemp + wuTemp;
console.log(avTemp);
}
The problem I am having is whenever I run the getAverage function it will return NaN since the other functions haven’t returned their data yet.
Is there a way to run a function after all of the previous functions returned their data?
Thanks
One of the easier ways is to use an async library like
asyncwhich can be found at https://github.com/caolan/async. You can use theparallelfunction to run the getters in parallel and then return when all of them have finished. The code ends up looking like:The other way to do is to have a global variable that contains the number of callbacks that you are waiting for. Then in the callbacks for each of the weather getters, decrement the counter. Before taking the average, just wait until the counter is at 0 (you can use setTimeout to wait a certain amount of time before checking again).