1

问这么微不足道的事情我觉得很愚蠢,但我真的想要最佳实践的答案(我不是在寻找“setTimeout”解决方案,除非没有其他可能——尽管我怀疑是这种情况)。

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

实际用途:我有一系列城市,我想用 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下面运行之前发生。

4

3 回答 3

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)用于迭代对象的属性,而不是数组的元素。

于 2012-05-30T00:47:34.427 回答
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);
        }
    });
于 2012-05-30T00:49:20.203 回答
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;
        }
    });
}
于 2012-05-30T00:47:26.077 回答