什么叫异步
异步(async)是相对于同步(sync)而言的,很好理解。
同步就是一件事一件事的执行。只有前一个任务执行完毕,才能执行后一个任务。而异步比如:
setTimeout(function(){ console.log('123');
}, 1000);console.log('hello');
setTimeout就是一个异步任务,当JS引擎顺序执行到setTimeout的时候发现他是个异步任务,则会把这个任务挂起,继续执行后面的代码。直到1000ms后,函数才会执行,这就是异步,在执行到setTimeout的时候,JS并不会傻呵呵的等着1000ms执行函数,而是继续执行了后面的代码。
1.2 为啥要在JS中使用异步
由于javascript是单线程的,只能在JS引擎的主线程上运行的,所以js代码只能一行一行的执行,不能在同一时间执行多个js代码任务,这就导致如果有一段耗时较长的计算,或者是一个ajax请求等IO操作,如果没有异步的存在,就会出现用户长时间等待,并且由于当前任务还未完成,所以这时候所有的其他操作都会无响应。
浏览器的加载时间线因为没有设置异步加载的话就会阻塞,得等js代码加载完成才会继续向下执行
1.浏览器开始解析页面 状态为loading
2.遇到外部文件创建线程加载,碰到没有设置async或defer的js文件,阻塞加载
3.文档解析完成 状态为interactive 触发DOMcontentLoaded事件
4.所有文档下载完成 状态为complete或者loaded,window触发onload事件
方案
第一种
// defer 兼容IE浏览器的老版本,内部文件和外部文件都可以用 ,对脚本执行进行延迟,直到页面加载为止
<script type="text/javascript" src="index.js" defer="defer">
var a = 1; //可以写入内部代码
</script>
第二种
// async 方式是页面加载完就执行,但是只能引用外部js文件,不能引入内部代码,不兼容IE浏览器老版本
<script src="index.js" async></script>
第三种
//创建一个script标签,插入到DOM中,加载完毕后callback 兼容性最好的
function asyncScript(url,callback){
var script = document.createElement('script');
if(script.readyState){
script.onreadystatechange = function(){//兼容IE
if(script.readyState== 'complete' || script.readyState== 'loaded'){
callback()
}else{
script.onload = function(){
callback();
}
}
}
}
script.src = url;
document.head.appendChild(script);
}