我懷疑這是不是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