用的最多的一种方式,又称阻塞模式,会阻止浏览器的后续处理,中止后续的解析,只有当当前加载完成,才能进行下一步操做。因此默认同步执行才是安全的。但这样若是js中有输出document内容、修改dom、重定向等行为,就会形成页面堵塞。因此通常建议把<script>标签放在<body>结尾处,这样尽量减小页面阻塞。javascript
<script src="http://webapi.amap.com/maps?v=1.4.7&key=您申请的key值"></script>
异步加载又叫非阻塞加载,浏览器在下载执行js的同时,还会继续进行后续页面的处理。主要有三种方式。vue
let script = document.createElement("script"); script.type = "text/javascript"; script.src = "//webapi.amap.com/maps?v=1.4.6&key="+key+"&callback=init"; script.onerror = reject; document.head.appendChild(script);
新的<script>元素加载 file1.js 源文件。此文件当元素添加到页面以后马上开始下载。此技术的重点在于:不管在何处启动下载,文件的下载和运行都不会阻塞其余页面处理过程,充分的利用了浏览器的多进程,但要注意,浏览器不保证文件加载的顺序。java
defer 属性规定是否对脚本执行进行延迟,直到页面加载为止。web
async的定义和用法(是HTML5的属性),async 属性规定一旦脚本可用,则会异步执行。
若是没有async和defer属性,那么浏览器会当即执行当前的js脚本,阻塞后面的脚本;若是有async属性,加载和渲染后续文档元素的过程将和当前js的加载与执行并行进行(异步);若是有defer属性,那么加载后续文档元素的过程将和 script.js 的加载并行进行(异步),可是 script.js 的执行要在全部元素(DOM)解析完成以后,DOMContentLoaded 事件触发以前完成。api
这种方式下,地图初始化的代码要放在 JS API 的脚本标签以后:数组
<script src="http://webapi.amap.com/maps?v=1.4.7&key=您申请的key值"></script> <script type="text/javascript"> var map = new AMap.Map('container', { center:[117.000923,36.675807], zoom:11 }); </script>
这种方式有缺点很明显,1:会致使加载页面变得很慢;2:单页应用的页面,若是页面中虽然用不到地图,可是也会加载这个js文件,这是没有必要的。promise
异步加载指的是为 JS API 指定加载的回调函数,在 JS API 的主体资源加载完毕以后,将自动调用该回调函数。回调函数应该声明在 JS API 入口文件引用以前,异步加载能够减小对其余脚本执行的阻塞,HTTPS 下咱们也建议使用异步方式:浏览器
<script type="text/javascript"> window.init = function(){ var map = new AMap.Map('container', { center:[117.000923,36.675807], zoom:11 }); } </script> <script src="http://webapi.amap.com/maps?v=1.4.6&key=您申请的key值&callback=init"></script>
或者安全
window.onLoad = function(){ var map = new AMap.Map('container'); } var url = 'http://webapi.amap.com/maps?v=1.4.6&key=您申请的key值&callback=onLoad'; var jsapi = doc.createElement('script'); jsapi.charset = 'utf-8'; jsapi.src = url; document.head.appendChild(jsapi);
如何在vue的组件化开发中引入高德地图呢?我写了一个loadMap.js文件app
export function MP(key) { return new Promise(function (resolve, reject) { window.init = function () { resolve(AMap) }; let script = document.createElement("script"); script.type = "text/javascript"; script.src = "//webapi.amap.com/maps?v=1.4.6&key="+key+"&callback=init"; script.onerror = reject; document.head.appendChild(script); }) }
而后在用到高德地图的vue的组件中
import {MP} from '../../../utils/loadMap'; MP('d275691902d1744cad9a7ddc1fc20657').then(function (AMap) { that.errNetwork = false; initAMapUI(); //这里调用initAMapUI初始化 that.initMap(AMap); }).catch(err=>{ that.errNetwork = true; })
在这儿我不只用到了高德地图,还用到的地图的UI库。在高德地图JavaScript API以后引入UI组件库的入口文件:
同步方式:
<!--引入高德地图JSAPI --> <script src="//webapi.amap.com/maps?v=1.3&key=您申请的key值"></script> <!--引入UI组件库(1.0版本) --> <script src="//webapi.amap.com/ui/1.0/main.js"></script>
异步方式
<!--异步加载 高德地图JSAPI ,注意 callback 参数--> <script src="//webapi.amap.com/maps?v=1.3&key=您申请的key值&callback=my_init"></script> <!--引入UI组件库异步版本main-async.js(1.0版本) --> <script src="//webapi.amap.com/ui/1.0/main-async.js"></script> <script type="text/javascript"> //JSAPI回调入口 function my_init() { initAMapUI(); //这里调用initAMapUI初始化 //其余逻辑 } </script>
关键是UI库依赖于地图js文件,在这里,咱们能够js加载完的回调onload函数和promise.all()函数来实现。loadMap.js文件以下:
export function MP(key) { const p1 = new Promise(function (resolve, reject) { window.init = function () { console.log('script1-------onload'); resolve(AMap) }; let script = document.createElement("script"); script.type = "text/javascript"; script.src = "//webapi.amap.com/maps?v=1.4.6&key="+key+"&callback=init"; script.onerror = reject; document.head.appendChild(script); }); const p2 = new Promise(function (resolve,reject) { let script2 = document.createElement("script"); script2.type = "text/javascript"; script2.src = "//webapi.amap.com/ui/1.0/main-async.js"; script2.onerror = reject; script2.onload = function(su){ console.log('script2-------onload',su); resolve('success') }; document.head.appendChild(script2); }); return Promise.all([p1,p2]) .then(function (result) { console.log('result----------->',result); return result[0] }).catch(e=>{ console.log(e);}) };
promise.all中的then的成功回调返回rusult是一个数组,分别表明p1和p2的结果,这里只返回p1的结果(map对象)就能够了。