day17JS-Cookle、WebStorage和Promise

1. 什么是Cookle

在网页中需要向当前电脑中存储一些数据,通过cookie可以存储。

Cookie :是一种由服务器发送到用户浏览器并保存在用户计算机上的小型文本文件,用于识别用户身份跟踪用户活动保存用户设置等。它通常包括名称、值、域名、路径、过期时间等字段

其它相关的概念:

  1. 程序运行在电脑上或者手机上,都叫做客户端或者服务端
  2. 客户端是用户显示使用的程序。
  3. 服务端是数据存储和操作的程序,为客户端提供数据的保障。
  4. 运行在插件或者其他程序中程序(runtime运行时)。

2. Cookle的使用方法

2.1 设置Cookle

document.cookie = "key=value";

注意!!!

如果key相同时就会覆盖上面key。

    <script>
        // 设置改变cookie
        document.cookie = "key=value";
        document.cookie = "name=xietian";
        // 如果key相同时就会覆盖上面
        document.cookie = "name=zhansang";
        document.cookie = "age=20";
        console.log(document.cookie);//key=value; name=zhansang; age=20
    </script>

2.2 获取Cookle

   <script>
        // 设置改变cookie
        document.cookie = "key=value"
        document.cookie = "name=xietian"
        // 如果key相同时就会覆盖上面
        document.cookie = "name=zhansang"
        document.cookie = "age=20"
        // 获取cookie, //key=value; name=zhansang; age=20
        function getCookie() {
            //split(";") ---> key=value name=zhansang age=20
            // 索引               0          1           2
            return document.cookie.split(";").reduce((value, item) => {
                //value是{},item是每一项的值
                //{key=value,name=zhansang,age=20}
                //split("=")---> [key,value] [name,zhansang] [age,20]
                var arr1 = item.trim().split("=")
                try {
                    value[arr1[0]] = JSON.parse(arr1[1]); //{key:value,name:zhansang,age:20}
                } catch (e) {
                    value[arr1[0]] = arr1[1];
                }
                return value;
            }, {})
        }
        var obj = getCookie();
        console.log(obj);
    </script>

 2.3 删除Cookle

js不能直接删除Cookle

1. 直接关闭浏览器。window需要再进程杀掉谷歌。

2. 点击浏览器中清除所有会话按钮。

3. 浏览器 --->设置 ---> 隐私和安全。

4. 设置Cookle的存活时长。谷歌浏览器禁止超过1年以上的存储。

知识点补充:

date.toUTCString(); :所有UTC都是国际时间格林尼治时间,将时间转换为格林尼治时间字符串。

var date=new Date();
date.setFullYear( 2099 );
//所有UTC都是国际时间格林尼治时间将时间转换为格林尼治时间字符串//谷歌浏览器禁止超过1年以上的存储
document.cookie="name=xietian;expires="+date.toUTCString();

3. Cookie的类型

       1. 会话Cookie(Session Cookies):这种类型的Cookie在浏览器关闭后就会被删除,主要用于保存用户的会话信息。由于它们不会在用户的计算机上长期保存,因此相对较为安全

        2. 持久Cookie(Persistent Cookies):与会话Cookie不同,持久Cookie会在用户的计算机上长期保存直到其过期时间到达被用户手动删除。这种类型的Cookie常用于保存用户的登录状态、个性化设置等信息

       3. 安全Cookie(Secure Cookies):安全Cookie只能通过HTTPS协议传输不能通过未加密的HTTP协议传输。这增加了Cookie在传输过程中的安全性。

       4. HttpOnly Cookie:HttpOnly是一个标志属性,用于防止JavaScript代码访问特定的Cookie。当设置了HttpOnly属性的Cookie被创建后,它将无法通过客户端脚本(如JavaScript)进行访问。这有助于减少跨站脚本攻击(XSS)的风险。

4. Cookle的特点

1、cookie的数据不能存储较大的数据(4-5K)。

2、cookie的数据会跟随访问服务端自动往返于客户端和服务端之间

3、cookie必须在使用web服务的情况下才可以使用

4、cookie存储是根据域名来存储不同域名之间不能相互访问

5、在前端发送请求到另一跨域地址中,也不会携带cookie跨域是只要么ip地址不同,要么端口号不同。

6、cookie是有时效性默认情况下cookie是关闭浏览器就销毁;cookie在浏览器中如果禁止cookie也不能存储cookie;浏览器可以随时销毁cookie,cookie可以通过设置保存时长来让cookie长期存储。

补充知识:

变量名.toUTCString(); :所有代UTC都是国际时间(格林尼治时间, 将时间转换为格林尼治时间字符串。

    <script>
        var date = new Date();
        date.setFullYear(2099);
        document.cookie = "name=xietian;expires=" + date.toUTCString();
    </script>

7、cookie存储按照路径存储的,每个路径下有自身的存储空间,相互之间方位。子级路径可以调用父级路径中cookie,但是父级路径无法调用子级路径中cookie,可以通过Path=设置路径让对应cookie存储在不同的级别上

5. Cookle的作用

       1. 会话管理:Cookie最初也是最主要的作用就是用于会话管理。当用户登录一个网站时,服务器会生成一个包含会话ID的Cookie并发送给浏览器,浏览器将这个Cookie保存在本地。此后,每次用户发送请求时,浏览器都会自动将这个Cookie发送给服务器,服务器通过会话ID识别用户身份,从而保持用户的登录状态。

       2. 个性化设置:Cookie还可以用来保存用户的个性化设置,如主题、语言、字体大小等。这样,当用户再次访问网站时,网站可以根据Cookie中的信息为用户提供更加个性化的体验。

        3. 购物车功能:在电子商务网站中,Cookie经常被用来实现购物车功能。当用户将商品添加到购物车时,这些信息会被保存在Cookie中。这样,即使用户关闭了浏览器或换了一台电脑,只要Cookie还在,购物车中的商品信息就不会丢失。

       4. 跟踪用户行为:网站可以使用Cookie跟踪用户在网站上的行为,如访问了哪些页面、停留了多长时间、点击了哪些链接等。这些数据对于网站优化、广告投放等都非常有价值。

        5. 第三方Cookie与广告定向:除了网站自己设置的Cookie外,还有一些第三方Cookie,它们通常由广告商或数据分析公司设置。这些Cookie可以用来跟踪用户在多个网站上的行为,从而为用户提供更加精准的广告定向服务。然而,这种跨站跟踪的行为也引发了关于隐私保护的争议。

6. Cookle可以做什么?

1、token(令牌)

       情况1:网页登录时发送用户名和密码给服务端,服务端会把用户名和密码加密后,得到字符串通过setCookie的方式设置会访问的客户端浏览器,在对应客户端浏览器中存储cookie中token内容,当刷新页面,或者重新打开网站时,因为cookie自动携带发送给服务端特性,这时候token就会发送给服务端,服务端对token解密。md5除外,md5不能解码。

       情况2 :或者将用户名和token发送给服务端,服务端去数据查询当前用户名的密码,然后根据指定的方式重新获取到token,然后比对发送来的toekn和服务端token是否一致来确定是否自动登录。

2、广告精准投放

3、临时存储当前用户对应的数据。

7. webStorage

webStorage分两类localStorage本地存储(长期存储)sessionStorage会话存储

localStorage可以看为一个对象,要存的key作为对象的属性就是这个结果

7.1 设置localStorage

设置方法一:localStorage.属性名 = "属性值";

设置方法二:localStorage.setItem("属性名", "属性值");

    <script>
        localStorage.name = "xietian";
        localStorage.age = 20;

        localStorage.setItem("sex", "男")
    </script>

7.2 获取localStorage

获取方法一:localStorage.属性名;

获取方法二:localStorage.getItem("属性名");

    <script>
        localStorage.name = "xietian";
        localStorage.age = 20;

        localStorage.setItem("sex", "男")


        // 获取
        console.log(localStorage.age);
        console.log(localStorage.getItem("name"));
        console.log(localStorage.getItem("sex"));
    </script>

7.3 删除localStorage

删除方法一:delete localStorage.属性名;

删除方法二:localStorage.removeItem("属性名");

    <script>
        delete localStorage.name;
        localStorage.removeItem("name");
    </script>

7.4 清空localStorage

localStorage.clear();

    <script>
        localStorage.clear();
        console.log(localStorage.length);
    </script>

8. Cookle和webStorage的区别

相同点cookie和webStorage只能存储字符串的内容,如果不是字符串需要先转换为字符串存储。

区别

1、LocalStorage是长期存储不会自动删除,可以通过浏览器删除,也可以手动删除, sessionStorage是会话级存储,如果关闭网页就是丢失,cookie也是会话级,当设置时效就会有时效性存储。

2、webStorage的存储比较大4-5M,cookie只有4-5K存储。

3、LocalStorage存储不区分路径sessionStorage即是同路径同页面不同的窗口打开数据不共享cookie根据不同路径存储

4、webStorage不会跟随发送通信发送给服务器,cookie会自动在前后端往返。

5、LocalStorage是可以侦听storage事件但只能针对window侦听。当跨页面设置storage时,另一个页面将会收到LocalStorage被改变的事件内容

这个页面:

    <script>
        window.addEventListener("storage", storageHandler);
        function storageHandler(e) {
            console.log(e);
        }
    </script>

 另一个页面:

<script>
    localStorage.num = 100;
</script>

6、LocalStorage可以用于大量数据的存储,比如部分js和css可以存储,用的时候可以直接调用不需要下载对应js和css

    <script>
        var script = document.createElement("script");
        script.innerHTML = localStorage.lodash;
        document.body.appendChild(script);

        console.log(_.chunk([1, 2, 3, 4, 5, 6], 3));
    </script>

9. 什么是Promise 

        Promise 是现代 JavaScript 中异步编程的基础。它是一个由异步函数返回的对象,可以指示操作当前所处的状态。在 Promise 返回给调用者的时候,操作往往还没有完成,但 Promise 对象提供了方法来处理操作最终的成功或失败。

使用方式:

    <script>
        var p = new Promise(function (resolve, reject) {
            // resolve();
            reject();
        })
    </script>

注意!!!

  1. 这个 resolvereject 两个回调函数名
  2. 执行resolve表示执行成功了,执行reject表示执行失败了
  3. 在Promise中执行了resolve就不会执行reject执行reject就不会resolve。只执行其中一个回调函数。

10. Promise 实例对象的方法

  1. then() :最多接受两个参数(可以写两个函数);如果then中的参数只有一个当执行了Promise中resolve就会执行then中的这个参数函数;如果then中的参数是两个当执行了Promise中resolve就会执行then中的第一个参数函数当执行了Promise中reject就会执行then中的第二个参数函数第二个参数函数相当于代替了catch。它立即返回一个等效的 Promise 对象,允许你链接到其他 Promise 方法,从而实现链式调用。
  2. catch():用于在 Promise 链进行错误处理,因为它总是会返回一个 Promise,所以它可以和 then() 方法一样被链式调用。

        当执行了Promise中resolve就会执行then中函数。

        当执行了Promise中reject就会执行catch中函数。

     3. resolve reject 都可以传参且仅能传一个参数

      p.then(function(){

      }).catch(function(){

      })

  resolve(1)中的1传入给了then中的函数的形参n。

<sceipt>
      // resolve和reject都可以传参,且仅能传一个参数
      new Promise(function(resolve,reject){
          resolve(1);
      }).then(function(n){
          console.log(n);//1
      })
</sceipt>

 Promise写法格式:

  写法一:
    function fn(){
          return new Promise(function(resolve,reject){
              setTimeout(function(){
                  // resolve();
                  reject();
              },1000)
          })
      }

      fn().then(function(){
          console.log("resolve");
      }).catch(function(){
          console.log("reject");//执行的是这里
      })

--------------------------------------------------------------
 写法二:
     function fn(){
          return new Promise(function(resolve,reject){
              setTimeout(function(){
                  // resolve();
                  reject();
              },1000)
          })
      }

      //then可以写两个函数
      fn().then(function(){
          // resolve执行
      },function(){
          // reject执行
      })

 案例1: 这个代码执行总共耗时3秒。每间隔一秒打印一个。现在怎么修改代码让红灯间隔1秒打印,黄灯需要在红灯执行完毕后的2秒才打印,绿灯则需要黄灯执行完毕后的3秒进行打印。

      setTimeout(function(){
          console.log("红灯");
      },1000)
      setTimeout(function(){
          console.log("黄灯");
      },2000)
      setTimeout(function(){
          console.log("绿灯");
      },3000)

案例2:下面这种写法叫做回调地狱,虽然能实现上述的要求,但是不建议这么写。

      //   回调地狱
        setTimeout(function () {
          console.log("红灯");
          setTimeout(function () {
            console.log("黄灯");
            setTimeout(function () {
              console.log("绿灯");
            }, 3000);
          }, 2000);
        }, 1000);

案例3:这个写法要写很多函数,也不建议这样写。

   setTimeout(fn1,1000);

      function fn1(){
          console.log("红灯");
          setTimeout(fn2,2000);
      }
      function fn2(){
          console.log("黄灯");
          setTimeout(fn3,3000);
      }
      function fn3(){
          console.log("绿灯");

      }

案例4:使用promise实现是最佳方案,它可以实现链式调用。

        function showLight(light, time) {
          return new Promise(function (resolve, reject) {
            setTimeout(function () {
              console.log(light);
              resolve();
            }, time);
          });
        }

        //链式调用
        showLight("红灯",1000)
        .then(function(){
          // 在then 中return一个Promise
          return showLight("黄灯",2000)
        }).then(function(){
          return showLight("绿灯",3000)
        }).then(function(){
          console.log("执行完成")
        })

 10.1 resolvereject的传参

resolvereject的传参有而只能传一个。

案例1:下面的案例 resolve("aaa")传参传给了then的形参value,使用执行结果为"aaa"。

     // 传参
       function fn(a){
          return new Promise(function(resolve,reject){
              setTimeout(function(){
                  if(a>0){
                      resolve("aaa");
                  }else{
                      reject("bbb")
                  }
              },1000)
          })
      }

      fn(10).then(function(value){
          console.log(value);
      }).catch(function(reason){
          console.log(reason);
      })

案例2:下面的案例reject("bbb")传参传给了catch的形参reason,使用执行结果为"bbb"。 

     // 传参
       function fn(a){
          return new Promise(function(resolve,reject){
              setTimeout(function(){
                  if(a>0){
                      resolve("aaa");
                  }else{
                      reject("bbb")
                  }
              },1000)
          })
      }

      fn(-2).then(function(value){
          console.log(value);
      }).catch(function(reason){
          console.log(reason);
      })

 10.2 then中关于return的问题

1. 如果在then中没有return一个Promise,则类似默认return一个Promise.resolve();传入参数为undefined

 function fn(a){
          return new Promise(function(resolve,reject){
              setTimeout(function(){
                  if(a>0){
                      resolve("aa")
                  }else{
                      reject();
                  }
              },1000)
          })
      }

      fn(1).then(function(value){
          console.log(value);
          // 如果在then中没有return一个Promise,则类似默认return一个Promise.resolve();
          //类似默认如下:
          // return new Promise(function(resolve){
          //     resolve();
          // })
      }).then(function(value){
          console.log(value);
      })

2.如果resolve执行时传参是Promise,相当于在执行了里面Promise后把里面resolve1的结果,传递外面resolve,然后再传递给then。


      new Promise(function(resolve,reject){
          // 如果resolve执行时传参是Promise,相当于在执行了里面Promise后把里面resolve1的结果,传递外面resolve,
          // 然后再传递给then
          resolve(new Promise(function(resolve1,reject1){
              resolve1(1)
          }))
      }).then(function(value){
          console.log(value);//1
      })

 3. 如果resolve重复调用执行只会执行第一个resolve。第一个resolve后面的resolve不会再执行。

  new Promise(function (resolve, reject) {
    resolve(2);//执行的是这个resolve,把参数传给了then中的value

    resolve(new Promise(function (resolve1, reject1) {
      resolve1(1)
    }))
  }).then(function (value) {
    console.log(value);//2
  })

案例:链式调用预加载问题(重点)

      function loadImage(src){
          return new Promise(function(resolve,reject){
              var img=new Image();
              img.src=src;
             img.addEventListener("load",()=>{
                  resolve(img);
             },{once:true})
          })
      }

      var arr=[];
      loadImage("./img/img_39.JPG")
      .then(function(img){
          arr.push(img);
          return loadImage("./img/img_40.JPG")
      }).then(function(img){
          arr.push(img);
          return loadImage("./img/img_41.JPG")
      }).then(function(img){
          arr.push(img);
          return loadImage("./img/img_42.JPG")
      }).then(function(img){
          arr.push(img);
          return loadImage("./img/img_43.JPG")
      }).then(function(img){
          arr.push(img);
          console.log(arr);
      })

10.3 Promise的状态机

      状态机运行原理: 刚开始的时候状态是pending,当执行resolve时,判断状态是不是pending,如果当前状态不是pending,就不会执行resolve函数了。如果是pending就会执行resolve函数,并且重新修改当前的状态为fulfilled,再次执行resolve,当前状态已经是fulfilled,所以不会执行resolve了。如果执行reject,当前状态还是pending状态,就会执行resolve,并且将状态修改为rejected,如果当前状态不是pending状态,就不会再次执行reject。

  • 待处理pending):初始状态,既没有被实现,也没有被拒绝。
  • 已实现fulfilled):意味着操作成功完成。当执行了resolve后就会触发状态改变为fulfilled。
  • 已拒绝rejected):意味着操作失败。当执行了reject后就会触发状态改变为rejected。

当我们在Promise中执行reject,但是没有设置then中第二个回调函数或者没有设置catch,就会报错

报错案例:

  var p=new Promise(function(resolve,reject){
          resolve()
      })

      console.log(p);

1.如果执行了finally部分的内容,finally回调函数中return的Promise是不会向下面的then去传递

2. 只能在then和catchreturn的Promise才能被下一个then收到

案例:

      function loadImage(src) {
        return new Promise(function (resolve, reject) {
          var img = new Image();
          img.src = src;
          img.onload=function(){
            resolve(img)
          }
          img.onerror=function(){
            reject(src);
          }
        });
      }

      var arr=[]
      loadImage("./img/img_31.JPG")
      .then(function(img){
        arr.push(img);
    
      }).catch(function(src){
      
      }).finally(function(){
        console.log("aaa");
        // 只能在then和catch中return的Promise才能被下一个then收到
        // finally回调函数中return Promise不会向下面的then去传递
        return loadImage("./img/img_39.JPG")
      }).then(function(img){
        console.log("bbb");
        arr.push(img);
        console.log(arr);
      })

11. Promise的静态方法

1. Promise.all([ ]) :同时异步多个Promise,并且返回resolve结果的列表。将所有需要Promise的对象放在数组中,然后把数组放在all里面,当then执行时,就会把每个Promise中resolve()传参的结果放在一个数组中传出。如果有一个出错,就会执行catch,不会执行then,必须保证所有Promise都会执行resolve

案例1:

    function loadImage(src) {
        return new Promise(function (resolve, reject) {
          var img = new Image();
          img.src = src;
          img.onload=function(){
            resolve(img)
          }
          img.onerror=function(){
            reject(src);
          }
        });
      }

    // all
    // 同时异步多个Promise,并且返回resolve结果的列表
    //   将所有需要Promise的对象放在数组中,然后把数组放在all里面,then执行时,就会把每个Promise中
    // resolve()传参的结果放在一个数组中,传出
    let arr=Array(5).fill(1).map((item,index)=>loadImage(`./img/img_${39+index}.JPG`));

    Promise.all(arr).then(function(list){
        console.log(list);
    })

 案例2:如果有一个出错,就会执行catch,不会执行then,必须保证所有Promise都会执行resolve。

    function loadImage(src) {
        return new Promise(function (resolve, reject) {
          var img = new Image();
          img.src = src;
          img.onload=function(){
            resolve(img)
          }
          img.onerror=function(){
            reject(src);
          }
        });
      }
    let arr=Array(5).fill(1).map((item,index)=>loadImage(`./img/img_${38+index}.JPG`));

    // 如果有一个出错,就会执行catch,不会执行then,必须保证所有Promise都会执行resolve
    Promise.all(arr).then(function(list){
        console.log(list);
    }).catch(function(e){
        console.log(e);
    })

2. Promise.allSettled([ ]) :同时异步多个promise在执行失败后仍然执行then,返回的内容中也是一个数组,数组中的内容是一个对象,对象中都有status值如果是"fulfilled"就是成功,如果是rejected就是失败的。如果成功,value就是返回的结果,如果失败,reason就是错误的结果。

 案例:

    function loadImage(src) {
        return new Promise(function (resolve, reject) {
          var img = new Image();
          img.src = src;
          img.onload=function(){
            resolve(img)
          }
          img.onerror=function(){
            reject(src);
          }
        });
      }
   let arr=Array(5).fill(1).map((item,index)=>loadImage(`./img/img_${38+index}.JPG`));

    Promise.allSettled(arr).then(function(list){
        // console.log(list);
        list=list.reduce(function(value,item){
            if(item.status==="fulfilled") value.push(item.value);
            return value;
        },[])
        console.log(list);
       
    })

3. Promise.race([ ]) :赛跑。同时对多个异步Promise执行,谁先执行完成resolve,就返回这个resolve的结果如果有一个Promise调用reject就不会调用then

    function loadImage(src) {
        return new Promise(function (resolve, reject) {
          var img = new Image();
          img.src = src;
          img.onload=function(){
            resolve(img)
          }
          img.onerror=function(){
            reject(src);
          }
        });
      }
    let arr=Array(5).fill(1).map((item,index)=>loadImage(`./img/img_${38+index}.JPG`));
    Promise.race(arr).then(function(img){
        console.log(img);
    })

4. Promise.any([ ]) :任意。同时对多个异步Promise执行,谁先执行完成resolve,就返回这个resolve的结果。 即是有reject,也会执行then

    function loadImage(src) {
        return new Promise(function (resolve, reject) {
          var img = new Image();
          img.src = src;
          img.onload=function(){
            resolve(img)
          }
          img.onerror=function(){
            reject(src);
          }
        });
      }
   let arr=Array(5).fill(1).map((item,index)=>loadImage(`./img/img_${38+index}.JPG`));
    Promise.any(arr).then(function(img){
        console.log(img);
    })

5. Promise.resolve() :无参,它作用等同于创建一个Promise,并且调用resolve。

6. Promise.reject() :无参,它作用等同于创建一个Promise,并且调用reject

Promise.resolve()
相当于
new Promise(function(resolve){
    resolve()
})
----------------------------------
Promise.reject();
相当于
new Promise(function(resolve,reject){
     reject()
 })

7. Promise. try(函数) :try()中传入一个函数,如果函数执行正确,返回的值将会返回到then中,如果错误返回catch。替代try catch。

注意!!!

 Promise. try() 只能执行同步操作不能执行异步操作执行异步操作会接收不到return 的返回结果。

 执行正确:

    Promise.try(function(){
        return 1;
    }).then(function(a){
        console.log(a,"aaa");//1,"aaa"
    }).catch(function(e){
        console.log(e,"eee");
    })


执行出错:

    Promise.try(function(){
        throw new Error("aa")
    }).then(function(a){
        console.log(a);
    }).catch(function(e){
        console.log(e);
    })

执行异步操作会接收不到return 的返回结果

     Promise.try(function(){
        setTimeout(function(){
          let a=1;
          return a++;
        },100)
    }).then(function(a){
        console.log(a);//undefined
    }).catch(function(e){
        console.log(e);
    })

8. Promise. withResolvers() : 无参,返回一个对象,对象中包括promise对象reject函数resolve函数。这个写法就不需要new 一个Promise对象。

     let promise=Promise.withResolvers();
     console.log(promise);

使用案例:就是把Promise的内容拆出来,独立使用

    // 就是把Promise的内容拆出来,独立使用
    let { promise, resolve, reject } = Promise.withResolvers();
    setTimeout(function () {
      resolve(10);
    }, 2000)

    promise.then((result) => {
      console.log(result);//10
    }).catch((err) => {

    });

12. async函数和await

  1. async是一个函数await使用在async中使用的关键词
  2. await 是等待,只能等待Promise对象执行resolve或者reject
  3. async函数返回一个Promise对象,在async函数中return的结果,将会被返回promise执行then所接受。

  4. await不能等待setTimeout只能等Promise的resolve

    async function fn() {
      return 1;
    }

    let result = fn();
    console.log(result);//Promise对象

    result.then(function (value) {
      console.log(value);//1
    })

 案例1:它会等待第一张图片加载完毕并且打印出来,再进行第二张图片的加载和打印。

    function loadImage(src) {
      return new Promise(function (resolve, reject) {
        var img = new Image();
        img.src = src;
        img.onload = function () {
          resolve(img);
        };
        img.onerror = function () {
          reject(src);
        };
      });
    }

    async function load() {
      // 在这里等待loadImage中Promise里面的resolve执行,加载是一个异步过程,
      //所以在这里不会继续向后执行。
      // 而是等待加载异步完成,并且执行resolve,把resolve返回的结果传递给了变量img1
      let img1 = await loadImage("./img/img_39.JPG");
      console.log(img1);

      let img2 = await loadImage("./img/img_40.JPG");
      console.log(img2);
    }
    load();

案例1的升级版:

    function loadImage(src) {
      return new Promise(function (resolve, reject) {
        var img = new Image();
        img.src = src;
        img.onload = function () {
          resolve(img);
        };
        img.onerror = function () {
          reject(src);
        };
      });
    }

    async function load() {
      let arr = []
      for (var i = 39; i < 44; i++) {
        let img = await loadImage("./img/img_" + i + ".JPG");
        arr.push(img);
      }
      console.log(arr);
    }

    load();

案例2: for循环本来是同步,因为await的使用,就会把for循环阻塞,等待resolve执行后才会继续执行。

    function setTime(time) {
      return new Promise(function (resolve) {
        setTimeout(function () {
          console.log(time);
          resolve();
        }, time)
      })
    }

    async function show() {
      // for循环本来是同步,因为await的使用,就会把for循环阻塞,等待resolve执行后才会继续执行
      for (var i = 1; i < 10; i++) {
        console.log(i);
        await setTime(i * 1000)
      }
    }
    show();

案例3:

    async function show() {
      // 这里并没有发生阻塞,await不能等待setTimeout,只能等Promise的resolve
      await setTimeout(function () {
        console.log("aa");
      }, 2000)
      console.log("bb");
    }
    show();
------------------------------------------------------
改进版:发生阻塞
    async function show() {
      await new Promise(function (resolve, reject) {
        setTimeout(function () {
          console.log("aa");
          resolve();
        }, 2000);
      });
      console.log("bb");
    }

    show();

案例4:

    async function fn1() {
      await new Promise(function (resolve, reject) {
        setTimeout(function () {
          console.log("aa");
          resolve();
        }, 2000);
      });
      console.log("a");
    }


    async function fn2() {
      await fn1();
      console.log("bb");
    }

    async function fn3() {
      await fn2();
      console.log("ccc");
    }

    fn3();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值