我怀疑这是不是markerArray
,它的抱怨,但markerArray[0]
这是不确定的。
您正在使用您在循环中创建的函数调用异步API。这些功能是关闭。他们每个都有一个持久参考到i
变量,而不是该值的副本,因为它是定义函数时。所以所有的函数都使用循环中最后的i
值,因为它们都没有运行,直到循环结束。因此,如果最后一个值i
已在循环中为5
,那么说,然后所有的功能将使用5
。
此外,在回调有机会运行之前,您会过早地执行alert
。您需要在回调之一中进行最后的处理(您可以使用柜台来了解它们何时发生的情况)。
您可以同时修改markerArray
问题和过早alert
这样的:
var markerArray = new Array();
var callcounter = 0;
for(var i in opts.markers)
{
address = opts.markers[i].address;
//alert(opts.markers[i].icon);
var geocoder = new google.maps.Geocoder();
++callcounter;
geocoder.geocode({ address: address }, buildCallback(i));
}
function buildCallback(index) {
return function(results, status) {
if (status == google.maps.GeocoderStatus.OK && results.length) {
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
position: results[0].geometry.location,
map: map
});
}
}
markerArray[index] = marker;
if (--callcounter === 0) {
// This was the last outstanding call
alert(markerArray[0]); // Always assuming there was a `0` in `opts.markers`
}
};
}
现在,回调超过您传递到buildCallback
功能index
参数关闭,而不是i
变量在主循环。当我们完成所有回调时,我们会发出警报,我们知道这是因为callcounter
(请参阅下面的注释,如果您的“竞赛状态”雷达正在关闭)。
所有这些都是因为关闭的方式。他们并不复杂(事实上,我写了一篇关于他们的博客文章,名为Closures are not complicated),但有些事情你需要牢固理解,以便“弄清楚”他们为什么要做他们所做的事情。
另外:你使用for..in
来循环通过opts.markers
,我怀疑这是一个数组。如果是,那么该代码就有问题需要解决。 for..in
不是通过阵列的指标循环,它是通过属性名称的对象的循环。 More here.您可能需要在您的for..in
循环中添加一些支票,或者只使用无聊的老式for
循环。
的Re counter
:要使用多线程编程的人,我的简单的“调度时增加它,处理时递减其”逻辑看起来像它建立了一个竞争条件(如果第一个被叫什么在第二个预定之前回来?)。但这不是浏览器JavaScript中的竞争条件,因为浏览器上的JavaScript是单线程的(或者如果您使用web workers,这种协作式多线程)。这里没有先发制人的多线程。直到他们有全部被安排,才会调用任何回调。
题外话:虽然var markerArray = new Array();
作品就好了,我建议你var markerArray = [];
代替。它更短;由于各种原因,实施可以优化一点(不是真的很重要);并且不可能有人隐藏了Array
这个符号。同样,任何时候只需要一个空白对象,请使用{}
而不是new Object()
。
是'opts.markers'数组还是对象? – jerone 2011-06-02 07:42:11
这可能不会解决您的问题,但不要使用'for ... in'来枚举数组:http://bonsaiden.github.com/JavaScript-Garden/#array.general – Domenic 2011-06-02 07:44:37
您可以插入控制台吗? log(markerArray)在markerArray [i] = marker之后;并在警报之前?并显示结果。 console.log的输出,您可以在firebug或其他javascript开发者工具中监视浏览器。 – Shamanu4 2011-06-02 07:44:44