在之前做过百度地图js开发的过程中(主要是用百度地图js的api写一些简单的demo,用来显示数据或者进行一些操作响应)
但这中间遇到了不少的问题,比如说上次写得一个网页,用不同的颜色(已经排序好的)将武汉市的不同区域显示。
想法是先定义一个名称数组{“武昌区”,”江汉区”……},然后定义一个颜色序列{000000,0000FF……},两者一一对应,然后调用百度地图中getBoundary服务查找区域名对应的区域多边形并涂上对应的颜色。
百度地图中的getboundary服务:1
2
3
4
5
6
7var bdary = new BMap.Boundary();
var name ="武汉";
bdary.get(name, function(es)
{
var ply = new BMap.Polygon(es.boundaries[0], {strokeWeight: 2, strokeColor: "#ff0000"}); //建立多边形覆盖物
map.addOverlay(ply);
}
把区域名作为参数然后在回调函数中用参数的方式来返回boundary结果
我就先用for循环,查找一次就给返回的多边形赋颜色
第一次执行成功了,但是刷新一次后颜色就全变了,并且每次打开该网页都会发现颜色顺序都不同。
查阅了一些js回调函数的知识后,终于理解了问题出现的原因
原来js执行机制是这样的,本身只有一个线程,按照顺序执行代码,但如果遇到回调函数的指令,则先把回调函数这一段代码抽出主线程,在系统资源空闲时执行,并且这里执行顺序也是随机的,也就是说,不能保证回调函数的执行顺序。
因此问题也就可以解释了,我是通过数组下标来对应多边形和颜色的,而js的变量机制导致在执行回调函数的时候不知道其对应的数组下标是多少,并且这一过程也是随机的,也就导致每次的颜色都不会对应。
这样问题来了:如何按照一定的顺序来执行回调函数。我思考很久后都不能解决,如果变量较少的时候可以通过给每一次执行都写上代码,但如果任务较多,或者任务数量不定的话就比较难解决了。
于是我将这个问题放到csdn论坛上,js板块的版主”showbo”大神给我一个很好地思路,就是用递归的方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27var addrs=['addr1','addr2'/*....*/]
var now=0;
getBound(addrs[now]);//////////
function getBound(name){
var bdary = new BMap.Boundary();
bdary.get(name, function(es)
{
var ply = new BMap.Polygon(es.boundaries[0], {strokeWeight: 2, strokeColor: "#ff0000"}); //建立多边形覆盖物
map.addOverlay(ply);
now++;
if(now<addrs.length)getBound(addrs[now]);////////////
}
}
思路就是用一个全局变量now来表示当前处理任务并且作为递归终止的条件,将递归函数的执行放到回调函数中,这样就可以保证第一个回调函数的执行完成后才会执行下一个回调函数。
按照这个思路,最终实现的颜色和地块的对应。
再后面我用固定代码的方法给每个多边形添加了操作相应函数,到这里一执行又发现这些操作都没用。
想想前文提到的js回调函数机制,系统是先执行了添加操作响应的代码再回到回调函数执行,而多边形的生成又是在回调函数中执行的,即添加操作响应的时候这个对象还没有生成,这些操作就当然不会有执行。
因此我就按照经验在生成多边形的代码下面加了一句setTimeout("eventOver();eventOut();",4000);
这句话的作用类似于C中的sleep,将系统的线程暂停四秒,等所有多边形生成完成后再执行后面的操作,当然这个四秒是根据经验来设置的,如果网速较差,就需要更长的时间。