我觉得愚蠢的问一些如此微不足道的事情,但我真的想要最佳实践答案(我不是在寻找“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
运行之前不会发生。
答案 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;
}
});
}