<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Promise和async/await

      1、promise對(duì)象

      promise 對(duì)象有三種狀態(tài):pending(進(jìn)行中)、fulfilled(已成功)和 rejected(已失敗)。promise 對(duì)象的狀態(tài)改變,只有兩種可能:從 pending 變?yōu)?fulfilled 和從 pending 變?yōu)?rejected。

      new Promise((resolve, reject) => {
        if() {
          resolve();
        }else {
          reject();
        }
      });
      const promise = new Promise(function(resolve, reject) {
        if (){
          resolve(value);
        } else {
          reject(error);
        }
      });

      promise 構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù),該函數(shù)的兩個(gè)參數(shù)分別是 resolve 和 reject,它們是兩個(gè)函數(shù),由 JavaScript 引擎提供,不用自己部署。

      resolve 函數(shù)將 promise 對(duì)象的狀態(tài)從“未完成”變?yōu)椤俺晒Α保磸?pending 變?yōu)?resolved)可以將數(shù)據(jù)作為參數(shù)傳遞出去。reject 函數(shù)的作用是,將 promise 對(duì)象的狀態(tài)從“未完成”變?yōu)椤笆 保磸?pending 變?yōu)?rejected),也可以將某些錯(cuò)誤信息作為參數(shù)傳遞出去。

      由于Promise 新建后會(huì)立即執(zhí)行,所以可以在 promise 外面再包裹一層函數(shù):

      function timeout(ms) {
        return new Promise((resolve, reject) => {
          setTimeout(resolve, ms, 'done');
        });
      }
      
      timeout(100).then((value) => {
        console.log(value);
      });

       請(qǐng)注意:在 promise 構(gòu)造函數(shù)中如果不 resolve 或者 reject 改變 promise 對(duì)象的狀態(tài)的話,后面的 then 是不會(huì)執(zhí)行的。但是如果在 then 中不改變狀態(tài),后面的鏈?zhǔn)?then 仍會(huì)執(zhí)行。

      //下面的then里面的程序不會(huì)執(zhí)行
      new Promise( (resolve, reject) => {
        console.log('promise');
      }).then( ()=>{
        console.log('resolve');
      }, ()=>{
        console.log('reject');
      })
      
      //下面的第一個(gè)和第二then里面的程序都會(huì)執(zhí)行
      new Promise( (resolve, reject) => {
        console.log('promise');
        resolve();
      }).then( ()=>{
        console.log('then1');
      }).then( ()=>{
        console.log('then2');
      })

       

      1.1、then() 方法

      Promise 實(shí)例是一個(gè)對(duì)象,不是一個(gè)函數(shù)。promise 實(shí)例生成以后,可以用 then 方法分別指定 resolved 狀態(tài)和 rejected 狀態(tài)的回調(diào)函數(shù)。

      new Promise().then(() => {}, () => {});
      let promise = new Promise(function(resolve, reject) {
        if (){
          resolve(value);
        } else {
          reject(error);
        }
      });
      
      promise.then(function(value) {
        console.log(value)
      }, function(error) {
        console.log(error)
      });

      then 方法可以接受兩個(gè)回調(diào)函數(shù)作為參數(shù)。第一個(gè)回調(diào)函數(shù)是 promise 對(duì)象的狀態(tài)變?yōu)?resolved 時(shí)調(diào)用,第二個(gè)回調(diào)函數(shù)是 promise 對(duì)象的狀態(tài)變?yōu)?rejected 時(shí)調(diào)用,第二個(gè)函數(shù)是可選的,不一定要提供。這兩個(gè)函數(shù)都接受 promise 對(duì)象傳出的值作為參數(shù)。

       

      1.2、then() 方法的鏈?zhǔn)綄懛?/h3>

      then 方法返回的是一個(gè)新的 promise 實(shí)例,因此可以采用鏈?zhǔn)綄懛ǎ?then 方法后面再調(diào)用另一個(gè) then 方法。

      1.2.1、then 方法里面返回一個(gè)確定值時(shí)

      在一個(gè) then() 方法里面你可以 return 一個(gè)確定的“值”,此時(shí) then 會(huì)將這個(gè)確切的值傳入一個(gè)默認(rèn)的新的 Promise 實(shí)例,并且這個(gè) Promise 實(shí)例會(huì)立即置為 fulfilled 狀態(tài),將 return 的值作為 resolve 方法的參數(shù)傳遞出去,以供接下來的 then 方法里使用。

      let p1 = new Promise((resolve,reject) => {
          resolve('aaa')
      })
      p1.then((data) => {
          data = data + 'bbb'
          return data  // 此時(shí)data會(huì)作為resolve的參數(shù)傳遞出去
      }).then((val) => {
          console.log(val + ' sucess');
      },(err) => {
          console.log(err + ' error');
      })
      
      //輸出: aaabbb sucess

       

      1.2.1、then 方法里面返回一個(gè) promise 實(shí)例

      如果 then 方法里面返回的還是一個(gè) promise 對(duì)象,這時(shí)后一個(gè)回調(diào)函數(shù),就會(huì)等待該 promise 對(duì)象的狀態(tài)發(fā)生變化,才會(huì)被調(diào)用。

      //第一個(gè)異步任務(wù)
      function a(){
        return new Promise(function(resolve, reject){
           resolve("a函數(shù)");
        });
      }
      //第二個(gè)異步任務(wù)
      function b(data_a){
        return new Promise(function(resolve, reject){
           console.log(data_a);
           resolve("b函數(shù)");
        });
      }
      
      //連續(xù)調(diào)用
      a().then(function(data){   
          return b(data);      // 此時(shí)then方法里面返回的是一個(gè)promise對(duì)象,后面的then會(huì)等待該promise對(duì)象的狀態(tài)發(fā)生改變才會(huì)被調(diào)用
      }).then((data) => {
          console.log(data + 'sucess')
      }, (err) => {
          console.log(err + 'rejected')
      })
      //輸出:a函數(shù)  b函數(shù)sucess

      上面的最后一個(gè) then 函數(shù)等待前面的 then 函數(shù)里面的 promise 對(duì)象狀態(tài)發(fā)生改變,如果變?yōu)?resolved ,就調(diào)用第一個(gè)回調(diào)函數(shù),如果狀態(tài)變?yōu)?rejected,就調(diào)用第二個(gè)回調(diào)函數(shù)。

      1.2.1、then 方法里面不返回

      如果 then 方法不返回?cái)?shù)據(jù),那么后面的 then 將無法獲取到前面的數(shù)據(jù),但是后面的 then 方法仍能執(zhí)行。

      //第一個(gè)異步任務(wù)
      function a(){
        return new Promise(function(resolve, reject){
           resolve("a函數(shù)");
        });
      }
      //第二個(gè)異步任務(wù)
      function b(data_a){
        return new Promise(function(resolve, reject){
           console.log(data_a);
           resolve("b函數(shù)");
        });
      }
      
      a().then(function(data){   
          console.log(data)    //不返回
      }).then((data) => {
          console.log(data + ' sucess')
      }, (err) => {
          console.log(err + ' rejected')
      })
      //輸出: a函數(shù)  undefined sucess

       

      1.3、catch() 方法

      Promise.prototype.catch方法是.then(null, rejection).then(undefined, rejection)的別名,用于指定發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)。

      p.then((val) => console.log(val))
        .then(null, (err) => console.log(err));
      // 相當(dāng)于
      p.then((val) => console.log(val))
        .catch((err) => console.log(err));

      catch 方法中斷調(diào)用鏈:

      在很多情況下,如果連續(xù)的幾個(gè)異步任務(wù),其中某個(gè)異步任務(wù)處理失敗,那么接下來的幾個(gè)任務(wù)很大程度上就不需要繼續(xù)處理了,我們可以使用 catch 方法來終止then的調(diào)用鏈。

      function a() {
         return new Promise(function (resolve, reject) {
             setTimeout(function () {
               reject("error");
             }, 1000);
         });
      }
      
      //這樣做不會(huì)中斷
      //下面輸出:222  333
      a().then(function (data) {
         console.log(111);
         return data
      }, function (data) {  //如果是這樣處理rejected狀態(tài),并不會(huì)中斷調(diào)用鏈
         console.log(222);        
         return data;
      }).then(function (data) {
         console.log(333);
      })
      
      //在調(diào)用鏈的末尾加上catch方法,當(dāng)某個(gè)環(huán)節(jié)的Promise的異步處理出錯(cuò)時(shí),將中斷其后的調(diào)用,直接跳到最后的catch
      //下面直接輸出: 'error'
      a().then(function (data) {
         console.log(111);
         return data
      }).then(function (data) {
         console.log(222);
      }).catch(function (e) {
         //rejected的狀態(tài)將直接跳到catch里,剩下的調(diào)用不會(huì)再繼續(xù)
         console.log(e);
      });

      使用 catch 方法時(shí),如果前面的函數(shù)里面有 reject 或者函數(shù)里面有錯(cuò)誤的話,就會(huì)被 catch 方法捕獲,立即跳轉(zhuǎn)到 catch 方法里執(zhí)行。前面的回調(diào)函數(shù)中,不管是運(yùn)行中有錯(cuò)誤,或者是執(zhí)行了 reject ,都會(huì)立即被 catch 方法捕獲。

       

      使用 catch 捕獲了錯(cuò)誤,catch 后面的代碼能繼續(xù)正常執(zhí)行。

      new Promise().then().catch(() => {
        console.log('catch 錯(cuò)誤')
      });
      console.log(111);  //這里的 111 仍能正常輸出

       

      2、async/await 方法

      async 方法里面有 await 命令,await 命令后面跟著異步操作(可以是請(qǐng)求接口或者其他異步操作等),這時(shí) async 函數(shù)會(huì)停下來,等待 await 命令后面的異步操作執(zhí)行完畢,將結(jié)果返回,然后再繼續(xù)執(zhí)行下去。如果后面再遇到 await 命令仍是如此,所以,async 函數(shù)里面可以看做是同步操作,語句都是一行一行地依次執(zhí)行的,語句執(zhí)行順序非常清晰。

      2.1、async 函數(shù)的定義形式

      // 函數(shù)聲明
      async function foo() {}
      const foo = async function () {};
      
      // 對(duì)象的方法
      let obj = { async foo() {} };
      
      // 箭頭函數(shù)
      const foo = async () => {};
      
      // Class 的方法
      class Storage {
        constructor() {
          this.cachePromise = caches.open('avatars');
        }
        async getAvatar(name) {
          const cache = await this.cachePromise;
          return cache.match(`/avatars/${name}.jpg`);
        }
      }

      2.2、async 函數(shù)里面的 await 命令

      注意,await 命令后面只能是 Promise 對(duì)象或者原始類型的值(數(shù)值、字符串和布爾值,但這時(shí)會(huì)自動(dòng)轉(zhuǎn)成立即 resolved 的 Promise 對(duì)象)。只有后面的 promise 對(duì)象返回了值 await 命令才算執(zhí)行完畢,程序才會(huì)繼續(xù)執(zhí)行。

      2.2.1、await 跟著 promise 對(duì)象

      一般來說,await命令后面應(yīng)該跟著一個(gè) Promise 對(duì)象,如果該 promise 對(duì)象觸發(fā)的是 resolve 方法,那么 await 就會(huì)接收到 resolve 方法的參數(shù),并將其返回。

      function timeout() {
        return new Promise((resolve) => {
            setTimeout(function (){
               resolve('aaa')
            },1000);
        });
      }
      async function asyncPrint() {
         console.log(await this.timeout());  //await會(huì)返回resolve的參數(shù)
         console.log(111);
      }
      asyncPrint(); //一秒鐘過后按順序執(zhí)行,依次輸出 aaa 111

       

      如果觸發(fā)的是 reject 方法,await 無法接收到 reject 返回的值,此時(shí)必須用 catch 方法來捕獲這個(gè)錯(cuò)誤,否則會(huì)報(bào)錯(cuò)。

      (1)可以用 try...catch 來捕獲異常

      注意,在 try...catch 里面捕獲異步操作的異常,必須使用 await 同步寫法,否則會(huì)捕獲不到。

      async created () {
          async function f() {
             await Promise.reject("出錯(cuò)了!!");
          }
          try {
             await f();   //注意,這里必須使用同步(await )的寫法,否則捕獲不到錯(cuò)誤
          } catch (error) {
             console.log(error);  //輸出  出錯(cuò)了!!
          }
      }

       

      (2)也可以在調(diào)用的時(shí)候直接在后面加上 catch 來捕獲異常。

      下面代碼中,await語句前面沒有return,但是reject方法的參數(shù)依然傳入了catch方法的回調(diào)函數(shù)。這里如果在await前面加上return,效果是一樣的。

      async function f() {
        await Promise.reject('出錯(cuò)了!!');
      }
      
      f().then(v => console.log(v)).catch(e => console.log(e))   //輸出: 出錯(cuò)了!!
      function timeout() {
          return new Promise((resolve, reject) => {
              setTimeout(function() {
                  reject("aaa");
              }, 1000);
          });
      }
      timeout().then(val => {
        console.log(val);
      }).catch(err => {
        console.log(err);  //捕獲到異常 輸出 aaa
      })

      reject 的參數(shù)會(huì)被后面第一個(gè)出現(xiàn)的 catch 方法捕獲到。

       

      任何一個(gè)await語句后面的 Promise 對(duì)象變?yōu)?code>reject狀態(tài),那么整個(gè)async函數(shù)都會(huì)中斷執(zhí)行。

      async function f() {
        await Promise.reject('出錯(cuò)了');
        await Promise.resolve('hello world'); // 不會(huì)執(zhí)行
      }

      有時(shí),我們希望即使前一個(gè)異步操作失敗,也不要中斷后面的異步操作。這時(shí)可以將第一個(gè)await放在try...catch結(jié)構(gòu)里面,這樣不管這個(gè)異步操作是否成功,第二個(gè)await都會(huì)執(zhí)行。

      async function f() {
        try {
          await Promise.reject('出錯(cuò)了');  //使用await寫法
        } catch(e) {
          console.log(e);
        }
        return await Promise.resolve('helloworld');
      }
      
      f().then(v => console.log(v))   //輸出: helloworld

       

      2.2.2、await 跟著原始類型的值

      await 命令后面只能是 Promise 對(duì)象或者原始類型的值,如果 await 命令后面是原始類型的值,則直接返回對(duì)應(yīng)的值。

      async function f() {
        // 等同于 return 123;
        let a = await 123;
        console.log(a)
      }
      f();   //輸出: 123

       

      2.2.3、await 后面跟其他類型的值將沒有效果

      function timeout() {
        setTimeout(() => {
           console.log('aaa');
        }, 1000);
      }
      async function asyncPrint() {
         await timeout();    //此時(shí)的await不起作用
         console.log(111);
      }
      asyncPrint();         //先輸出111,后輸出aaa,并不能起到順序執(zhí)行的作用

       

      2.3、async 函數(shù)返回的值是一個(gè) promise 對(duì)象

      async函數(shù)返回的是一個(gè) Promise 對(duì)象,可以使用then方法添加回調(diào)函數(shù)。

      async函數(shù)內(nèi)部return語句返回的值,會(huì)成為then方法回調(diào)函數(shù)的參數(shù)。

      async function f() {
        return 'hello world';
      }
      
      f().then(v => console.log(v))  // "hello world"

      async函數(shù)返回的 Promise 對(duì)象,必須等到內(nèi)部所有await命令后面的 Promise 對(duì)象執(zhí)行完,才會(huì)發(fā)生狀態(tài)改變,除非遇到return語句或者拋出錯(cuò)誤。也就是說,只有等到async函數(shù)內(nèi)部的await 后面的異步操作執(zhí)行全部完,promise 對(duì)象狀態(tài)才會(huì)發(fā)生改變,然后才能執(zhí)行后面添加的then方法指定的回調(diào)函數(shù)。

      let p1 = new Promise((resolve,reject)=>{
         resolve('aaa')
      })
      let p2 = new Promise((resolve,reject)=>{
         resolve('aaa')
      })
      async function getUrl(url) {
         let response = await p1;
         let html = await p2;
         return url;
      }
      getUrl('http://www.baidu.com').then((val) => {
         console.log(val)
      })    //只有等到 p1 和 p2 都執(zhí)行完畢后才會(huì)調(diào)用then里面的回調(diào)函數(shù)輸出值,輸出:http://www.baidu.com

       

      2.4、async函數(shù)的鏈?zhǔn)接梅?/h3>

      async函數(shù)返回的值是一個(gè) promise 對(duì)象,這意味著我們?cè)趫?zhí)行完一個(gè) async 函數(shù)完后,可以在后面接著寫 then 等操作。

      2.4.1、async 函數(shù)返回原始類型值的情況

      async 函數(shù)如果最后是返回原始類型的值,那么該原始類型值會(huì)被當(dāng)做被 resolve 的值,我們可以在該函數(shù)后面加 then 來繼續(xù)執(zhí)行操作,獲取返回的值。

      async function main () {
          //返回原始類型值會(huì)被包裝為一個(gè)立即resolve的Promise對(duì)象
          return 123;    //相當(dāng)于 return Promise.resolve(123),其實(shí)也是一個(gè)promise對(duì)象
      }
      //此時(shí)的鏈?zhǔn)綄懛?/span>
      const data = main()      //此時(shí)data是一個(gè)promise對(duì)象,可以加then來繼續(xù)執(zhí)行操作 
      data.then(num => {
           console.log(num);    //輸出123
      })

       

      2.4.2、async 函數(shù)返回promise對(duì)象的情況

      其實(shí) async 函數(shù)返回原始類型值也相當(dāng)于是返回一個(gè) promise 對(duì)象,此時(shí)我們可以在另一個(gè) async 函數(shù)里用 await 接收 resolve 出來的值,也可以直接加 then 繼續(xù)操作。

      async function main () {
          return new Promise((resolve, reject) => {
             resolve(123)
          })
      }
      
      //此時(shí)的鏈?zhǔn)綄懛?/span>
      //可以在另一個(gè) async 函數(shù)里面接收它的結(jié)果
      async function main2 () {
          const data = await main();   //await后面是一個(gè)promise對(duì)象,會(huì)等到該promise對(duì)象將值resolve出來
          console.log(data);           //輸出12,此時(shí)的data已經(jīng)獲取到了resolve出來的值。
      }
      main2()

       

      請(qǐng)注意:async 函數(shù)里,在 await 后面返回的值并不是 async 函數(shù)返回的值。

      //下面的async函數(shù)相當(dāng)于沒有返回值,其他函數(shù)就接收不到
      async function main () {
          new Promise((resolve, reject) => {
             return 123;
          })
      }
      
      async function main2 () {
          const data = await main();   
          console.log(data);           //輸出 undefined,因?yàn)閙ain函數(shù)根本沒有返回值。
      }
      main2()

       

      2.5、async 函數(shù)的錯(cuò)誤處理

      如果await后面的異步操作出錯(cuò),或者是await 后面的 promise 對(duì)象被 reject,那么async函數(shù)后面的語句將不會(huì)執(zhí)行,async 函數(shù)會(huì)立即返回一個(gè) rejected 狀態(tài)的promise對(duì)象

      async function f() {
        await new Promise(function (resolve, reject) {
          throw new Error('出錯(cuò)了');
        });
      }
      f().then(v => console.log(v)).catch(e => console.log(e))
      // Error:出錯(cuò)了
      
      async function f() {
        await Promise.reject('出錯(cuò)了??!');
      }
      f().then(v => console.log(v)).catch(e => console.log(e))   //輸出: 出錯(cuò)了!!

      防止出錯(cuò)的方法,也是將其放在try...catch代碼塊之中。

      async function f() {
        try {
           await new Promise(function (resolve, reject) {
              throw new Error('出錯(cuò)了');
           });
        }catch (e) {}
           return await ('hello world'); //這里仍然能執(zhí)行
        }
      f().then((data) => {console.log(data);});    //輸出: hello world

       

      2.6、await只會(huì)阻塞本函數(shù)體內(nèi)的語句

      需要注意,await函數(shù)只會(huì)阻塞本函數(shù)體內(nèi)的語句,不是本函數(shù)體內(nèi)的語句并不會(huì)導(dǎo)致堵塞。

      比如下面的代碼,將會(huì)輸出222   aaa   111,也就是說await只會(huì)堵塞本身函數(shù)體 asyncPrint 內(nèi)的語句,輸出222的語句并不會(huì)堵塞。所以我們大可以用 await 來進(jìn)行異步操作。

      function timeout() {
        return new Promise((resolve) => {
            setTimeout(function (){
               resolve('aaa')
            },1000);
        });
      }
      async function asyncPrint() {
         console.log(await this.timeout());  //await會(huì)返回resolve的參數(shù)
         console.log(111);
      }
      
      asyncPrint(); //一秒鐘過后按順序執(zhí)行,依次輸出 aaa 111
      console.log(222)

      下面代碼將輸出:222  333  aaa  第1個(gè)  bbb   第2個(gè)  ccc  第3個(gè)

      function timeout() {
          return new Promise((resolve) => {
              setTimeout(function () {
                  resolve('aaa')
              }, 3000);
          });
      }
      function timeout2() {
          console.log(222);
          return new Promise((resolve) => {
              setTimeout(function () {
                  resolve('bbb')
              }, 3000);
          });
      }
      function timeout3() {
          console.log(333);
          return new Promise((resolve) => {
              setTimeout(function () {
                  resolve('ccc')
              }, 3000);
          });
      }
      
      async function asyncPrint() {
          console.log(await this.timeout());  //await會(huì)返回resolve的參數(shù)
          console.log('第1個(gè)');
      }
      async function asyncPrint2() {
          console.log(await this.timeout2());  //await會(huì)返回resolve的參數(shù)
          console.log('第2個(gè)');
      }
      async function asyncPrint3() {
          console.log(await this.timeout3());  //await會(huì)返回resolve的參數(shù)
          console.log('第3個(gè)');
      }
      
      asyncPrint();
      asyncPrint2();
      asyncPrint3();

       

      posted @ 2019-08-05 23:04  wenxuehai  閱讀(566)  評(píng)論(0)    收藏  舉報(bào)
      //右下角添加目錄
      主站蜘蛛池模板: 国产美女裸身网站免费观看视频| 影音先锋人妻啪啪av资源网站| 久青草国产在视频在线观看| 国产偷人妻精品一区二区在线| 国产日韩精品一区二区三区在线| 欧美亚洲一区二区三区在线| 中美日韩在线一区黄色大片| 久草网视频在线观看| 海口市| 亚洲av中文乱码一区二| 九九热视频在线精品18| 日本熟妇色xxxxx日本免费看| 四虎库影成人在线播放| 国产精品人成视频免| 亚洲自偷自拍另类小说| 亚洲国产av无码精品无广告 | 娇小萝被两个黑人用半米长| 影视先锋av资源噜噜| 蜜臀av一区二区精品字幕| 久久精品一区二区东京热| 亚洲一区二区精品极品| 美女人妻激情乱人伦| 国产精品日韩精品日韩| 91中文字幕在线一区| 国产午夜免费高清久久影院| 18禁无遮挡啪啪无码网站破解版 | 国产亚洲国产精品二区| 国产在线观看免费观看| 国产99re热这里只有精品| 国语精品自产拍在线观看网站| 边添小泬边狠狠躁视频| 国产永久免费高清在线| 黔东| 精品偷拍一区二区三区在| 综合色一色综合久久网| 18禁裸乳无遮挡自慰免费动漫| 亚洲第一成人网站| 国产精品国三级国产av| 久久中文字幕无码专区| 亚洲精品一区二区三区大| 国产目拍亚洲精品二区|