第三十節(jié): ES6 async與await

1.async 函數(shù) & await

1.1. async含義

ES2017 標準引入了 async 函數(shù)辛藻,使得異步操作變得更加方便。

async 函數(shù)是 Generator 函數(shù)的語法糖谆奥。

什么是語法糖?
意指那些沒有給計算機語言添加新功能,而只是對人類來說更“甜蜜”的語法蜕着。語法糖往往給程序員提供了更實用的編碼方式,有益于更好的編碼風格红柱,更易讀承匣。不過其并沒有給語言添加什么新東西。

反向還有語法鹽:
主要目的是通過反人類的語法锤悄,讓你更痛苦的寫代碼韧骗,雖然同樣能達到避免代碼書寫錯誤的效果,但是編程效率很低零聚,畢竟提高了語法學習門檻袍暴,讓人齁到憂傷些侍。。政模。

1.2. async的使用

async函數(shù)使用時就是將 Generator 函數(shù)的星號(*)替換成async岗宣,將yield替換成await,僅此而已淋样。

//創(chuàng)建異步函數(shù)
async function show() {
    let result =await 20;
    console.log(result);
  }   
  show()
async function show (){
    await '33'
}
let p1 = show();

1.2.1 await配合async使用
async function fn(){  // async 表示異步,這個函數(shù)里面有異步的任務
    let result = await xxxx;  // 表示等待await后面的結(jié)果需要等待,等出來在處理
}

1.3. async函數(shù)對 Generator 函數(shù)的區(qū)別:

(1)內(nèi)置執(zhí)行器耗式。

Generator 函數(shù)的執(zhí)行必須靠執(zhí)行器,而async函數(shù)自帶執(zhí)行器趁猴。也就是說刊咳,async函數(shù)的執(zhí)行,與普通函數(shù)一模一樣儡司,只要一行娱挨。

(2)更好的語義。

async和await枫慷,比起星號和yield让蕾,語義更清楚了。async表示函數(shù)里有異步操作或听,await表示緊跟在后面的表達式需要等待結(jié)果探孝。

(3)正常情況下,await命令后面是一個 Promise 對象誉裆。如果不是顿颅,會被轉(zhuǎn)成一個立即resolve的 Promise 對象。

(4)返回值是 Promise足丢。

async函數(shù)的返回值是 Promise 對象粱腻,這比 Generator 函數(shù)的返回值是 Iterator 對象方便多了。你可以用then方法指定下一步的操作斩跌。

進一步說绍些,async函數(shù)完全可以看作多個異步操作,包裝成的一個 Promise 對象耀鸦,而await命令就是內(nèi)部then命令的語法糖柬批。

  async function show() {
    let result =await new Promise((res)=>{   //后面跟Promise,里面定義一個回調(diào)函數(shù)袖订。await會始終等到后面的Promise調(diào)用then方法氮帐,把then方法的值取出來賦值給result
      setTimeout(()=>{
        res(50)
      },3000)
    });
    console.log(result);
  }   
  show()
    async function show() {
      let result = await new Promise((res) => {   //后面跟Promise,里面定義一個回調(diào)函數(shù)洛姑。await會始終等到后面的Promise調(diào)用then方法上沐,把then方法的值取出來賦值給result
        setTimeout(() => {
          res(50)
        }, 3000)
      });
      console.log(result);
      return result + 20;
    }
    show()
    let res = show();
    console.log(res);
    res.then((data) => { console.log(data); })
1.4. async 的特點
  1. await 只能放到async函數(shù)中使用
  2. 相比generator 語義化更強
  3. await后面可以是promise對象,也可以是數(shù)字,字符串,布爾值
  4. async 函數(shù)返回的是一個promise對象
  5. 只要await 語句后面的Promise的狀態(tài)變成reject,那么整個async函數(shù)會中斷執(zhí)行
1.4.1 驗證async函數(shù)返回一個promise對象
async function fn(){

}
console.log(fn());  //Promise

// 使用
async function fn(){
    return 'welcome';
}
fn().then(res => {
    console.log(res);    // welcome
})

1.4.2 如果async函數(shù)中出錯
async function fn(){
    throw new Error('Error 出錯了')
}
fn().then(res => {
    console.log(res);
}).catch(err => {
    console.log(err);  //  Error 出錯了
})
    async function show() {
      throw new Error('Error 出錯了')
    }
    let res = show();
    console.log(res);
    res.then((data) => { console.log(data); })
      .catch(err => {
        console.log(err);  //  Error 出錯了
      })
    async function show() {
      try {
        throw new Error('Error 出錯了')
        let result = await 20;
        console.log(result);

      } catch (err) {
        console.log(err)
      }
    }
    let promise = show()
    promise.then((data) => console.log(data))
1.4.3 如果await后面的語句出錯,函數(shù)后面將中斷執(zhí)行

錯誤在成功之后,錯誤和成功都會執(zhí)行

async function fn(){
    let a = await Promise.resolve("成功了");
    console.log(a);
    await Promise.reject('出錯了')   //await 后面如果是失敗狀態(tài)promise 這條語句后面的代碼都不會執(zhí)行
}
fn().then(res => {
    console.log(res);   
}).catch(err => {
    console.log(err);
})
// 打印結(jié)果
// 成功了
// 出錯了

但是如果錯誤在前,成功將不會執(zhí)行

async function fn(){
    await Promise.reject('出錯了')
    let a = await Promise.resolve("成功了");
    console.log(a);
}
fn().then(res => {
    console.log(res);
}).catch(err => {
    console.log(err);   
})
// 打印結(jié)果
// 出錯了

1.5. 解決async函數(shù)中的報錯

如何解決async函數(shù)中拋出錯誤,影響后續(xù)代碼執(zhí)行;

這個問題比較嚴重,雖然是async的特點,但是我又不知道程序什么時候出錯,所以我不希望出錯的代碼影響后續(xù)運行,導致程序中斷

1.5.1使用 try { } catch (){}
async function fn(){
    try{
        await Promise.reject('出錯了')
    }catch(e){
        let a = await Promise.resolve("成功了");
        console.log(a);
    }
}

1.5.2 添加catch 捕獲錯誤

本來await后面的就是promise,那么我們就可以直接使用catch處理

async function fn(){
    await Promise.reject('出錯了').catch(err=>{
        console.log(err);
    })
    let a = await Promise.resolve("成功了");
    console.log(a);
}

其實跟網(wǎng)絡打交道的都不保險,你不可能給每一個await后面的promise對象都加catch

1.5.3 統(tǒng)一捕獲錯誤

個人建議,只要有await的地方都try catch掉 然后統(tǒng)一處理結(jié)果

try {
    let f1 = await Promise.resolve('成功了');
    let f2 = await Promise.resolve('成功了');
    let f3 = await Promise.reject('出錯了');
}catch(e){}

1.5.4 也可以是用Promise.all()方法

如果你多次請求的數(shù)據(jù)之間沒有關(guān)聯(lián),就可以使用Promise.all()

// async 
async function fn(){
    let [f1,f2,f3] = await Promise.all([
        Promise.resolve('成功了1'),
        Promise.resolve('成功了2'),
        Promise.resolve('成功了3')
    ])


    console.log(f1);
    console.log(f2);
    console.log(f3);
}
fn();

同時配合解構(gòu)處理

例子:

  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
  <script>
    async function show() {
      let p1 = await new Promise((res, rej) => {
        $.ajax({
          url: 'https://jsonplaceholder.typicode.com/todos/1',
          success: function (data) {
            console.log(data);
            res()
          },
          error: function (err) {
            rej()
          }
        })
      });

      let p2 = await new Promise((res, rej) => {
        $.ajax({
          url: 'https://jsonplaceholder.typicode.com/todos/2',
          success: function (data) {
            console.log(data);
            res()
          },
          error: function (err) {
            rej()
          }
        })
      });
    }
    let pp = show();

generator只是一個過渡期,強烈建議大家用async就可以了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末楞艾,一起剝皮案震驚了整個濱河市参咙,隨后出現(xiàn)的幾起案子龄广,更是在濱河造成了極大的恐慌,老刑警劉巖蕴侧,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜀细,死亡現(xiàn)場離奇詭異,居然都是意外死亡戈盈,警方通過查閱死者的電腦和手機奠衔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來塘娶,“玉大人归斤,你說我怎么就攤上這事〉蟀叮” “怎么了脏里?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長虹曙。 經(jīng)常有香客問我迫横,道長,這世上最難降的妖魔是什么酝碳? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任矾踱,我火速辦了婚禮,結(jié)果婚禮上疏哗,老公的妹妹穿的比我還像新娘呛讲。我一直安慰自己,他們只是感情好返奉,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布贝搁。 她就那樣靜靜地躺著,像睡著了一般芽偏。 火紅的嫁衣襯著肌膚如雪雷逆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天污尉,我揣著相機與錄音膀哲,去河邊找鬼。 笑死十厢,一個胖子當著我的面吹牛等太,可吹牛的內(nèi)容都是我干的捂齐。 我是一名探鬼主播蛮放,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼奠宜!你這毒婦竟也來了包颁?” 一聲冷哼從身側(cè)響起瞻想,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎娩嚼,沒想到半個月后蘑险,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡岳悟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年佃迄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贵少。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡呵俏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出滔灶,到底是詐尸還是另有隱情普碎,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布录平,位于F島的核電站麻车,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏斗这。R本人自食惡果不足惜动猬,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望表箭。 院中可真熱鬧枣察,春花似錦、人聲如沸燃逻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伯襟。三九已至猿涨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間姆怪,已是汗流浹背叛赚。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留稽揭,地道東北人俺附。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像溪掀,于是被迫代替她去往敵國和親事镣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1.async 函數(shù) & await 1.1. async含義 ES2017 標準引入了 async 函數(shù)揪胃,使得異...
    時光如劍閱讀 709評論 0 8
  • 含義 ES2017 標準引入了 async 函數(shù)璃哟,使得異步操作變得更加方便氛琢。 async 函數(shù)是什么?一句話随闪,它就...
    硅谷干貨閱讀 393評論 0 0
  • 在前一篇文章[http://www.reibang.com/p/7ee993ec1a80]中阳似,最后提到 Gene...
    越前君閱讀 1,352評論 0 5
  • 含義 async函數(shù)是Generator函數(shù)的語法糖,它使得異步操作變得更加方便铐伴。 寫成async函數(shù)撮奏,就是下面這...
    oWSQo閱讀 1,993評論 0 2
  • 含義 async 函數(shù)是什么?一句話当宴,它就是 Generator 函數(shù)的語法糖挽荡。 依次讀取兩個文件,可以寫成asy...
    Upcccz閱讀 388評論 0 0