作者TonyQ (沉默是金。)
看板Ajax
标题Re: [ js ] 关於.getLatLng的问题
时间Mon May 24 07:14:04 2010
※ 引述《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
1F:推 atoi:谢谢喔,目前应该OK了 05/24 10:29