js异步加载与时间线

一.进程:当一个软件打开的时候最少有一个进程(比方:打开Chrome浏览器,至少对应一个进程)

线程:(1).一个进程至少有一个线程

(2).单线程:JavaScript就是一个单线程

(3).多线程

生活中的例子:一个网站(单线程:从开始输入网址开始,这个线程只能服务一个客户;多线程:则服务多个客户)

二.同步与异步

同步的单线程:流程实例(开始进店--接待--坐下来--点餐--下单--自己去食堂炒菜--所有的菜豆都烧好--端给你--吃--付钱--清理)

 

同步模式,又称阻塞模式,会阻止浏览器的后续处理,停止后续的解析,只有当当前加载完成,才能进行下一步操作。所以默认同步执行才是安全的。但这样如果js中有输出document内容、修改dom、重定向等行为,就会造成页面堵塞。所以一般建议把 < script > 标签放在< body>结尾处,这样尽可能减少页面阻塞。
< script src=“http://yourdomain.com/script.js”>< /script> //同步

 

异步的单线程:流程实例(开始进店--接待--坐下来--点餐--下单--交给厨房去炒菜------

异步在加载的过程中产生一个子进程去加载当前程序,自己去执行下一个程序

特点:单线程的异步就是多线程,只不过用异步的方式表现出来了

三.异步加载的三种方式

第一种方式:<script defer></script>

第二种方式:(只能加载src中的脚本,不能把代写在script标签中)

<script async="async" src="03.js">

//注意,不要再这里写代码

</scipt>

第三种方式:除了以上两种方法,还有一种兼容自己封装的异步加载方式,即动态添加script标签也能实现异步加载。

 

<script defer>  //只针对IE浏览器 
js代码...//    
</script>

<!-- 第二种 async 只能加载src中的脚本,不能把代码也在script标签中 -->
<script async="async" src="03.js">
    var abc = 123;   //不能这样写
</script>

 <script>
 //异步的过程
    var img = document.createElement("img");
    img.src =      //这个也是异步的
    var script = document.createElement("script");
    script.src =   //这个也是异步的
    document.head.appendChild(script);
</script>

(在异步执行的模式下,每一个异步的任务都有其自己一个或着多个回调函数,这样当前在执行的异步任务执行完之后,不会马上执行事件队列中的下一项任务,而是执行它的回调函数,而下一项任务也不会等当前这个回调函数执行完,因为它也不能确定当前的回调合适执行完毕,只要引它被触发就会执行)

四.三种解决异步加载的

(1).解决方法一:过滤

使用定时器(等加载完后再去执行)

<script>
    // 异步的过程
    var script = document.createElement("script");
    script.src = "test.js";
    document.head.appendChild(script);        
     setTimeout("test()",100)    //等待加载完成以后执行,加载时间不确定,不推荐

(2).解决方法二:onload事件(等待加载完成之后在执行)

    onload 事件      -->    等待加载完成以后执行的事件
    包括link标签中的   href 加载并下载完成
    包括img 的src 加载并下载完成
    script.onload = function(){     //老版本的IE不支持
        test()
    }

(3).解决方法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script>
    function add(url,callback){//回调函数callback
        var script=document.createElement("script");
        if(script.readyState){
            console.log(script.readyState)
            script.onreadystatechange=function(){//事件监听状态变化的事件
                if(script.readyState=="compele" || script.readyState=="loaded"){
                    callback();
                }
            }
        }else{
            script.onload=function(){
                callback();
            }
        }
        script.src=url;
        document.head.appendChild(script);
    }
    add("test.js",function(){
        test()
    })
    </script>
</body>
</html>