Re: [ js ] 關於.getLatLng的問題

看板Ajax作者 (沉默是金。)時間15年前 (2010/05/24 07:14), 編輯推噓1(100)
留言1則, 1人參與, 最新討論串3/3 (看更多)
※ 引述《lovelycateye (我還想要更多力量)》之銘言: : ※ 引述《atoi (atoi)》之銘言: : : 假設Universities[j][i]是存放校名,這變數的row是表示某一區 : : 而column表示該區的一些學校,myGeocoder = new GClientGeocoder(); 這行寫過了 : : 以下就是code的部分: 其實要看重點... : : for(var i = 0 ; i < Universities[j].length ; i++ ) ^ : : { : : myGeocoder.getLatLng( Universities[j][i], function(point) ^^^^^^^^^^^^^^^ : : { : : if(!point) : : window.alert(Universities[j][i] + " not found"); ^ : : else : : { : : window.alert(Universities[j][i]); : : } : : } : : ); : : } : : 而這個code跳出來的視窗裡面寫的都是同一個校名,而且都是該區的最後一個 : : 學校,不知道是為什麼,可以請大家幫忙看看嗎,謝謝了 : 1.沒用過google maps api的人,天曉得GClientGeocoder,是什麼東西。 這個問題還不需要知道... : 2.怕的話可以在for迴圈裡面加上 myGeocoder.setCache(null); 不是這問題... : 3.重點來了 : 這是ajax,我沒記錯的話,不可能有辦法預期哪一個geoencode會先完成。 : 換句話說你可能是abc三個學校照順序傳,但是他是完成就call你的function, : 所以有可能是bca的順序叫到。 : 因此你根本不會知道第一個回傳的經緯度是不是真的是你第一個叫他做的地址。 這點沒錯,是需要考慮的問題, but 不是主要問題... : 4.你的i和j在你的callback裡面應該是看不到才對的。 : callback function裡面只看得到point和Universities[]才對。 根據 js 的 var scope , 只要是在同一function closure有定義,是看得到的.... : 當然,我不知道你有沒有把i和j另外存放,不過看起來是沒有。 : 5.最後,這應該要去google版問吧? (雖然回文的我沒資格說就是=3=) 本板歡迎跟 js 有關的問題... : 6.補充:方便的話附上完整code比較容易看出問題在哪,因為這code一看就是有問題。 : 7.不負責任猜測:八成是你有把i和j存起來,然後迴圈跑一次就存一次i和j, : 所以大概你會跳出的都是最後一個學校。 其實這是個經典問題, 因為所有 function 共用 i 這個變數,而且又是非同步的, 所以 i 這個變數因為迴圈執行的太快,getLatLng跑得比較慢, 所以function callback又是在一定時間之後, 所以就導致 i 很有可能已經跑完迴圈,改變成最後一個迴圈值, 這個問題的最基本型態會長這樣 for(var i=0;i<10;++i){ setTimeout(function(){ alert(i); },3000); } 因為setTimeout是非同步的,且3000ms遠超過for需要跑完的時間, 所以最後取得的 i 都會是10. 至於解決方案,一個是作queue,讓他依序進行。 如 var j=0; for(var i=0;i<10;++i){ setTimeout(function(){ alert(j); j++; },3000); } (這是要在確定他的行為是同時、依序回來的前提下,ajax情形不一定適用...) 另一個是by object存放的方式進行. 這裡我是用setTimeout+字串的性質來作一個比較取巧的說明 for(var i=0;i<10;++i){ setTimeout("alert('"+i+"');",3000); } 一般來講比較正常的作法會是在callback 傳入一個專屬的object, 由他去記得原本傳入的值,這也是為什麼大部分的js callback都有提供, 由母函式帶值給子函式的理由。 回到原本的例子,其實以他的需求,我比較建議他用getLocations去拿... 回傳值會是Placemark 帶 adress/point 所以就可以改寫成 Universities=[["元智大學","淡江大學","中正大學","嘉義大學","火星大學"]]; var j=0; for(var i = 0 ; i < Universities[j].length ; i++ ) { geocoder.getLocations( Universities[j][i], function(point) { if(!point.Placemark){ alert(point.name+" not exist"); }else{ alert(point.name+":"+point.Placemark[0].Point.coordinates); } } ); } -- btw 我覺得官方gmap reference寫得還蠻不詳細的。 :p -- 我:一半的日子讓你說,我聽你說你的所有______________________________________ ______________________________________一半的日子我想說,對你說過去的所有:我 _______________________________________________________ 在討論中妥善扮演兼具聆聽與分享的角色,是我們一生的課題。 _______________________________________________________ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.137.196.9

05/24 10:29, , 1F
謝謝喔,目前應該OK了
05/24 10:29, 1F
文章代碼(AID): #1B-RQ_9s (Ajax)
討論串 (同標題文章)
文章代碼(AID): #1B-RQ_9s (Ajax)