深入浅出百度地图API开发系列(3):模块化设计

     在前面两张简单介绍了百度地图API的基础知识和使用之后,我们来分析一下百度地图API的基本架构,了解一下基本架构可以帮助我们更清晰的了解API的功能和调用过程,也就可以帮助我们在实际开发中可以更方便的组织自己的代码。因为百度地图API内部有很多函数都是异步执行的,我们大家都知道js是单线程程序,所有异步代码的执行都必须在同步代码执行之后的。所以如果我们自己写代码进行API开发的时候,如果在同步代码中使用一些函数报错 undefined的话,很有可能就是API内部的异步代码未执行完造成的。这样的情况,我们也就只需要将自己的同步代码转为异步执行就可以了。

  好的,废话不多说了,先来张图说明一下百度地图API的功能。

   

    地图展示所包含的功能就是百度地图API的一些基础功能,包括地图显示,控件,覆盖物,地图工具等这些都是靠js和html就可以实现的。比如覆盖物就是通过js生成dom元素在地图上显示的,而检索功能就必须得依赖后端的服务了,百度地图API的前端与检索功能的底层服务中间有一层phpui代理,phpui的主要作用就是接受api前端的检索请求,然后转发给底层服务返回数据,百度地图API的前端跨域请求并不是以ajax的方式去请求的,而是动态生成script标签去加载的。内部会生成一个随机的回调函数传给后端,回调函数用来处理返回数据的。

  或许这样的脑图功能点更清楚些。各位也先不要晕。这些功能后续慢慢来消化。

  百度地图API作为一个使用量很大的前端框架,如果这些所有的代码都放在一个文件里面,呵呵,可以想象文件肯定非常大,这对于前端的性能来说简直是噩梦,所以百度地图API的设计也是模块化的,但是这种模块化和现在主流的AMD、CMD思想不一样的,当然最终加载实现的原理是一样的,也是通过动态script标签去获取异步模块文件,但是百度地图API的模块化设计是09年就已经行成,而那时候AMD还不知道是什么东西,所以地图API的模块化设计没有id的概念,只有文件的概念,以文件名+MD5标识模块文件名,模块之间的依赖关系也是在编码设计的时候就已经预先定义好的,内部代码中保存有模块之间的依赖数组,加载某一模块的时候,先通过模块依赖数组获得相关的依赖模块文件,最后统一将模块名合成字符串打包加载模块文件。加载完之后进行本地localStorage存储,这样在下次获取模块文件的时候首先检查本地存储,如果有的话直接获取本地文件。这样也是减少了网络请求。

  百度地图API的模块化是按照接口与实现分离的思想设计的,首先有一个类声明文件,类声明中预先定义了需要对外暴露的接口,但是接口的真正实现是放在异步文件中的。比如现在有一个map.js 表示map这个模块,map.js中先声明很多接口函数,但是函数体并不是真正的执行代码,或只是含有一些必要的代码,保证在类实现文件未加载的时候调用接口不报错,而真正的实现文件map_Impl.js对map.js中的声明接口都进行了覆盖,所以当加载完map_Impl.js之后真正的接口实现也就覆盖了预先声明的接口。

  之所以这样设计,也是考虑到前端的性能,因为在保证首图加载的情况下,一些不是立即需要的模块和接口是不需要首图加载的时候去执行的,这样将功能模块化。模块设计也按照接口与实现分离的方式,尽可能的减少同步文件的大小。保证地图首图的加载速度。也就是所说的按需加载。

  这样的设计其实和Google Map是一致的。当然Google一直是互联网的老大哥,好的东西当然需要借鉴了。

  我们来根据示例分析一下地图API的地图加载过程。

<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=*****"></script>
<script type="text/javascript">
var mp = new BMap.Map('map_container', {
    enableHighResolution: true
});
mp.centerAndZoom('北京', 15);
mp.enableScrollWheelZoom();

</script>

  首先加载http://api.map.baidu.com/api?v=2.0&ak=***** 获取地图引导文件。获取文件如下图:

  通过document.write的方式加载真正的地图主文件,getscript就可以获取地图api的压缩过后的主脚本文件了。获取主文件之后,就可以调用BMap对象了,可以生成Map实例去load地图了。

  在Map加载地图的时候实际有一些模块还是异步获取的,利用Chrome的开发者工具抓取一下网络请求如下:

  如上图所示,getmodules就是获取异步模块的请求,异步文件会覆盖一些主文件中类的接口方法。模块名是按照脚本文件名++文件md5加密组成,这样加md5的方式可以保证模块更新的时候加载最新的模块文件。

  所以,综上所述,百度地图API在加载地图的过程中,首先是api请求获取地图引导文件,然后引导文件去加载地图主文件,地图主文件有一些同步代码文件合并压缩而成,在同步文件代码执行的过程,在按需去加载异步文件。异步文件会相应覆盖一些同步文件的接口。最后获取地图瓦片图的时候也是相应的瓦片管理模块去实现最终的图片加载过程。加载过程中还包含计算中心点,根据第一章介绍的坐标系概念计算所需的图块信息,计算过程相对比较复杂,暂不累赘。各位也只需了解地图API的加载过程即可。

原文地址:https://www.cnblogs.com/shortbaby/p/4830069.html