我觉得问这么琐碎的事情很愚蠢,但我真的想要最佳实践答案(我不是在寻找“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
之前发生。
最佳答案
由于您的问题不清楚,我猜测您希望在完成所有地理编码调用后处理 all_the_pins 数组
。因为地理编码函数调用是异步的,所以您必须跟踪所有地理编码调用何时完成,然后您才能使用最终数组。
如果是这样,你可以这样做:
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)
用于迭代对象的属性,而不是数组的元素。
关于Javascript 回调时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10808586/