2012-04-30 26 views
0

所以我試圖在JavaScript中運行一個函數,但是我需要所有其他函數在該啓動之前運行並完成。下面的代碼(對不起,我知道這是很長,但它的唯一途徑我可以說明發生了什麼):其他完成後的消防功能javascript

 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+"&deg;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+"&deg;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+"&deg;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+"&deg;F</p>"); 
     } 
    }); 
} 

function getAverage() { 
    avTemp = wbTemp + wwTemp + yahooTemp + wuTemp; 
    console.log(avTemp); 
} 

我遇到的問題是,每當我運行getAverage函數將返回NaN的,因爲其他功能的避風港尚未返回他們的數據。

是否有一種方法可以在所有先前函數返回其數據之後運行函數?

感謝

+0

不是簡單地將調用移到getWorldWeather(zipCode)之後出現;工作? – ccKep

回答

3

更簡單的方法之一是使用異步庫,如async可以在https://github.com/caolan/async找到。您可以使用parallel函數並行運行獲取程序,然後在所有程序都完成後返回。該代碼最終看起來像:

async.parallel([ 
    function(callback){ 
     setTimeout(function(){ 
      callback(null, 'one'); 
     }, 200); 
    }, 
    function(callback){ 
     setTimeout(function(){ 
      callback(null, 'two'); 
     }, 100); 
    }, 
], 
// optional callback 
function(err, results){ 
    // the results array will equal ['one','two'] even though 
    // the second function had a shorter timeout. 
}); 

的另一種方法做的是有包含您正在等待回調數的全局變量。然後在每個天氣獲得者的回調中,遞減計數器。在取平均值之前,只需等到計數器爲0(您可以使用setTimeout等待一段時間再重新檢查)。

+0

我要試試這個。謝謝! – Vinny

1

要長話短說:從getJSON回調中調用getAverage,即,你叫getWorldWeather(zipCode);之後。

+0

我不認爲這會起作用,因爲沒有辦法確定哪個ajax調用首先返回。如果getWorldWeather首先返回,平均值將不正確。 – Bill

+0

@Bill,你絕對正確!你的答案是正確的。 – bfavaretto

0

確實有。你將需要做所謂的方法傳遞,或者做回調。

這裏是你將如何去了解它的未經測試例如:http://jsfiddle.net/UDbeV/

讓我更詳細地解釋它。

var i = 0; 
loopCount = function() { 
    i++; 
    if (i > 5) { 
     getAverage(); 
    } 
}); 

所以我們創建了一個名爲loopCount的函數來存儲計數器。每次它叫,我們增加1。

其反讓回調傳遞給你的方法:

getYahooWeather(WOEID, callback); 
    getWeatherbug(zipCode, callback); 
    getWeatherUnderground(zipCode, callback); 
    getWorldWeather(zipCode, callback); 
    callback(); 

現在我們要轉變職能,讓第二個參數:

function getYahooWeather(x, callback) { ... 

最後,在每個塊的結尾處,我們要稱之爲:

$.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 + "&deg;F</p>"); 
    callback(); 
}); 

回調檢查「它是否被調用了足夠的次數(即:從平均之前你正在做的呼叫數量),然後調用getAverage();

可能有更有效的方式來做到這一點,但它是星期一:P此外,它是未經測試,所以如果你去用它,你需要大概砍了一點。 :o)