在其他人完成javascript之后触发函数

Fire function after others complete javascript

本文关键字:函数 之后 javascript 其他人      更新时间:2023-09-26

所以我正在尝试在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,因为其他函数尚未返回其数据。

有没有办法在前面的所有函数返回其数据后运行函数?

谢谢

一种更简单的方法是使用像async这样的异步库,它可以在 https://github.com/caolan/async 找到。 您可以使用 parallel 函数并行运行 getter,然后在所有 getter 完成后返回。 代码最终看起来像:

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 等待一定的时间,然后再检查)。

简而言之:从getJSON回调中调用getAverage,即在调用getWorldWeather(zipCode);后立即调用。

肯定有。您将需要执行所谓的方法传递或进行回调。

这是一个未经测试的示例,说明您将如何做到这一点: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 此外,它是未经测试的,所以如果你使用它,你可能需要稍微破解它。