0

そのため、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を返すことです。

以前のすべての関数がデータを返した後に関数を実行する方法はありますか?

ありがとう

4

3 に答える 3

3

簡単な方法の 1 つは、 https://github.com/caolan/asyncにあるような非同期ライブラリを使用するasyncことです。関数を使用して getter を並行して実行し、すべてが終了したら戻ることができます。コードは次のようになります。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.
});

もう 1 つの方法は、待機しているコールバックの数を含むグローバル変数を用意することです。次に、各ウェザー ゲッターのコールバックで、カウンターをデクリメントします。平均を取る前に、カウンターが 0 になるまで待ちます (setTimeout を使用して、再度チェックする前に一定時間待つことができます)。

于 2012-04-30T03:54:51.980 に答える
1

簡単に言うとgetAverage、コールバック内からgetJSON、つまり を呼び出した直後に呼び出しますgetWorldWeather(zipCode);

于 2012-04-30T03:52:00.253 に答える
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();

ここで、2 番目のパラメーターを許可するように関数を変更する必要があります。

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)

于 2012-04-30T04:11:47.443 に答える