javascript 时间线和异步
1时间线的步骤
1.创建Document对象,开始解析web页面,解析HTML元素和他们的文本内容后添加Element对象和Text节点到文档中。这个阶段Document。readyState = "loading"。
2.遇到link外部css,创建线程加载,并继续解析文档。
3.遇到script外部js,并且没有设置async , defer ,浏览器加载,并阻塞,等待js加载完成并执行该脚本,然后继续解析文档
4.遇到script外部js,并且设置有async,defer 浏览器创建线程加载,并继续解析文档,对于async属性的脚本,脚本加载完成后立即执行(异步禁止使用docuemnt.write())。
5.遇到img标签等,先正常解析dom结构,然后浏览器异步加载src,并继续解析文档
6.当文档解析完成,document.readyState = "interactive";
7.文档解析完成后,所有设置有defer的脚本会按照顺序执行。
8..当文档解析完成之后,document对象触发DOMContentLoaded事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段
9.当所有saync的脚本加载完成并执行后,img等加载完成后,document.readyState = "complete" window对象触发load事件
10.从此,页面以异步响应方式处理用户输入,网络事件等。
2什么是异步加载
javascript 的介绍是单线程 解释行 弱类型
真正的单线程是上一步没有完成下一步就无法继续就比如代码里有外部文件需要下载的时间下载没有完成的话下一步就不会执行
那样的话渲染页面的时间就会非常的长用户等待的时间也会增加而异步操作会避免这一个问题,如果代码遇见异步操作时,主线程会将这个异步操作交给子线程
让子线程完成而主线程继续执行之后的代码,这样大大的节约了时间,也加快的页面渲染的速度。让两个任务同时进行
所以javascript其实是单线程异步,也可以叫做多线程,的只是在表面上是单线程的而已。
<script async="async"><script>// 只要设置了defer属性 这个scrip标签就为异步
<script async="async"><script> //只要设置了async属性 这个script标签就为异步
<script> var script = document.createElement("script"); //动态创建了script 标签 script.src = "02.js" //变成了异步的,代码还要继续往下面走,02.js创建线程自己去下载 </script>
当然这里02.js外部文件下载也需要时间的如果下载没有完成里面的代码和方法函数是无法运行运行了会报错的。
解决的方法就是加一个定时器
setTimeout(function() { //确保02.js下载完成 fun() //这里的fun()是02.js里的一个方法 }, 100)
function loadScript(url, callback) {// 第一个参数是文件名,第二个参数是需要加载的函数 var script = document.createElement("script"); // script.src = url; //考虑到网速快的情况 // 进行判断 if (script.readyState) { script.onreadystatechange = function() { //代码走到这里的时候url就已经下载完成 if (script.readyState == "complete" || script.readyState == "loaded") { callback() } } } else { script.onload = function() { callback() } } script.src = url; document.head.appendChild(script); // 加入进去代码都执行完成了,就没有用了 }