Javascript回调时间

时间:2012-05-30 00:35:20

标签: javascript

我觉得愚蠢的问一些如此微不足道的事情,但我真的想要最佳实践答案(我不是在寻找“setTimeout”解决方案,除非别无其他可能 - 尽管我怀疑是这种情况。) / p>

快速浏览:我有一个数组,我想从回调中推送到。在我填充数组后,我想在回调之外使用它。

实际用途:我有一系列城市,我想用Google的API对它们进行地理编码,并使用所有生成的LatLng填充数组。稍后我将使用它们创建标记对象,将它们添加到群集器中,无论如何。

coder = new google.maps.Geocoder();
$places = ['Truro, NS', 'Halifax, NS', 'Sydney, NS', 'Dartmouth, NS'];
all_the_pins = Array();
for(i in $places){
    var $place = $places[i];
    coder.geocode({address:$place}, function(res, stat){
        switch(stat){
            case 'OK':
                all_the_pins.push(res[0].geometry.location);
                break;
        }
    });
}
console.log(all_the_pins);

编辑:澄清问题: 问题不在于范围问题或all_the_pins变量是否为全局变量,如果要在回调中检查all_the_pins,您将看到它是同一个变量(这是被推到)。问题是因为推送发生在回调中,所以在console.log运行之前不会发生。

3 个答案:

答案 0 :(得分:1)

由于您的问题不明确,我猜测您希望在完成所有地理编码调用后处理all_the_pins array。由于地理编码函数调用是异步的,因此您必须跟踪所有地理编码调用何时完成,然后才能使用最终数组。

如果是这样,你可以这样做:

var coder = new google.maps.Geocoder();
var $places = ['Truro, NS', 'Halifax, NS', 'Sydney, NS', 'Dartmouth, NS'];
var all_the_pins = Array();
var remaining = $places.length;
for (var i = 0, len = $places.length; i < len; i++)
    var $place = $places[i];
    coder.geocode({address:$place}, function(res, stat){
        switch(stat){
            case 'OK':
                all_the_pins.push(res[0].geometry.location);
                break;
        }
        --remaining;
        if (remaining == 0) {
            // all_the_pins data is set here
            // call a function and pass the array to it or put your
            // code here to process it
            console.log(all_the_pins);
        }
    });
}

注意:我还改为使用正确类型的for循环来迭代数组。 for (var i in xxx)用于迭代对象的属性,而不是数组的元素。

答案 1 :(得分:1)

不,setTimeout在这里绝对没用。如果您有多个异步请求,并且想要在所有这些请求回调时执行某些操作,则唯一的可能性是计数器。在最后一次回调之后,打开请求的数量将减少为null;然后执行你想要的东西。

var coder = new google.maps.Geocoder();
var places = ['Truro, NS', 'Halifax, NS', 'Sydney, NS', 'Dartmouth, NS'];
var all_the_pins = [];
for (var i=0; i<places.length)
    coder.geocode({address:places[i]}, function(res, stat){
        if (stat == 'OK')
            all_the_pins.push(res[0].geometry.location);
        else
            all_the_pins.push(stat);

        // counter is length of results array:
        if (all_the_pins.length >= places.length) {
            console.log(all_the_pins);
        }
    });

答案 2 :(得分:0)

你的其他代码可以存在于另一个回调中吗?我会设置一个函数,只在被调用x次后(即输入数组的长度)执行。

coder = new google.maps.Geocoder();
$places = ['Truro, NS', 'Halifax, NS', 'Sydney, NS', 'Dartmouth, NS'];
all_the_pins = Array();

function myCallback(count, totalCount, all_the_pins) {
    if (count != totalCount) return;

    console.log(all_the_pins);
}

count = 1;

for(i in $places){
    var $place = $places[i];
    coder.geocode({address:$place}, function(res, stat){
        switch(stat){
            case 'OK':
                all_the_pins.push(res[0].geometry.location);

                myCallback(count, $places.length, all_the_pins);
                count++;
                break;
        }
    });
}