<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          不是吧?async/await異常捕獲你還在用try-catch~

          共 4196字,需瀏覽 9分鐘

           ·

          2023-05-28 04:28

          寫(xiě)在前面

          不知道大家項(xiàng)目里面是怎么處理 async/await 的異常,我斗膽在我們項(xiàng)目里翻了一下,發(fā)現(xiàn)大量使用 try-catch 來(lái)處理 async/await 異常。

          a8563dea4afd2331cf195f11a010c44c.webptry-awati-catch.png

          首先說(shuō)明一下, try-catch 處理并沒(méi)有什么問(wèn)題,我只是覺(jué)得這么寫(xiě)代碼會(huì)有點(diǎn)亂,感覺(jué)代碼邏輯像是斷層了一樣,不易理解;

          其次是代碼冗余問(wèn)題,單個(gè) try-catch 就占了好幾行代碼,如果每個(gè)請(qǐng)求的地方都添加 try-catch,就會(huì)顯得代碼很臃腫。 而對(duì)于這種大量相同的冗余代碼,完全可以用一種通用的函數(shù)來(lái)替代。

          async/await 是在 ES2017 中引入的,目的是為了讓異步操作更加直觀、方便,同時(shí)也解決了 Promise 的回調(diào)地獄問(wèn)題。想必這些概念大家都已經(jīng)了解了,那么我們?yōu)槭裁匆东@ async/await 的異常呢?它們是在什么時(shí)候發(fā)生異常呢? 帶著問(wèn)題我們一起看一下本文。

          什么時(shí)候會(huì)請(qǐng)求異常

          我們都知道 await 后面一般都是異步請(qǐng)求,異步請(qǐng)求發(fā)生異常的原因大致有以下幾種:

          1. 網(wǎng)絡(luò)問(wèn)題導(dǎo)致,網(wǎng)絡(luò)斷開(kāi)連接,請(qǐng)求不到;
          2. 網(wǎng)絡(luò)慢導(dǎo)致異步請(qǐng)求超時(shí)。

          什么情況下需要處理請(qǐng)求異常

          一旦有以上情況出現(xiàn),這個(gè)異步請(qǐng)求就會(huì)產(chǎn)生異常,而 JavaScript 又是一個(gè)單線程語(yǔ)言,代碼報(bào)錯(cuò)后就會(huì)導(dǎo)致后面的代碼無(wú)法繼續(xù)執(zhí)行,所以此時(shí)就需要添加 try-catch 來(lái)捕獲異步請(qǐng)求的異常,使得代碼可以繼續(xù)向后執(zhí)行。

          但有必要為所有的異步請(qǐng)求都加 try-catch 嗎?

          我研究了下我們項(xiàng)目的代碼,異步請(qǐng)求加了 try-catch 處理的,有以下幾種情況:

          多個(gè)異步請(qǐng)求串行

                
                try?{
          ?//?獲取列表list
          ?const?list?=?await?getList(params)
          ?//?獲取單個(gè)詳情
          ?const?info?=?await?getListById(list[0]?.id)
          }?catch?{}

          前一個(gè)異步請(qǐng)求的返回結(jié)果,會(huì)作為后一個(gè)異步請(qǐng)求的請(qǐng)求參數(shù)使用,所以一旦前一個(gè)請(qǐng)求異常,后面的請(qǐng)求肯定會(huì)異常,所以需要添加 try-catch 處理。

          處理異步請(qǐng)求的 loading 狀態(tài)

                
                loading.value?=?true
          try?{
          ?//?獲取列表list
          ?const?list?=?await?getList(params)
          }?finally?{
          ?loading.value?=?false
          }

          一般我們處理異步請(qǐng)求前,會(huì)為其添加 loading 狀態(tài),而一旦請(qǐng)求異常出現(xiàn)時(shí),如果不加 try-catch 時(shí)就會(huì)導(dǎo)致頁(yè)面一直處于 loading 狀態(tài)。所以需要在finally中將 loading 狀態(tài)置為 false,catch中處理時(shí)需要外部再處理一次。

          那么,我們?nèi)绾蝺?yōu)雅的處理異步請(qǐng)求中的 try-catch 呢?

          處理方法

          使用 Promise 處理

          首先需要明確一點(diǎn):正常情況下,await 命令后面是一個(gè) Promise 對(duì)象[1]。所以它本身就可以使用.catch來(lái)捕獲異常,那么像上面第二種只是處理 loading 狀態(tài)的操作,完全可以在.catch進(jìn)行處理,然后用if判斷來(lái)控制提前退出,沒(méi)必要寫(xiě) try-catch 這種冗余代碼。

                
                loading.value?=?true
          let?res?=?await?getList().catch(()?=>?(loading.value?=?false))
          if?(!res)?return
          //?請(qǐng)求成功后正常操作

          await-to-js 處理函數(shù)

          簡(jiǎn)單的異步請(qǐng)求我們可以使用上面這種方法,但遇到多個(gè)異步操作時(shí),就需要借助我們今天要說(shuō)的await-to-js[2]這個(gè)庫(kù),它的介紹很簡(jiǎn)單:無(wú)需 try-catch 即可輕松處理錯(cuò)誤。

          而且源碼[3]賊簡(jiǎn)單,就 23 行代碼,我們一起來(lái)看看。

                
                /**
          ?*?@param?{?Promise?}?promise
          ?*?@param?{?Object=?}?errorExt?-?Additional?Information?you?can?pass?to?the?err?object
          ?*?@return?{?Promise?}
          ?*/

          export?function?to<T,?U?=?Error>(
          ??promise:?Promise<T>,
          ??errorExt?:?object,
          ):?Promise<[U,?undefined]?|?[null,?T]>?
          {
          ??return?(
          ????promise.then?<
          ????[null,?T]?>
          ????((data:?T)?=>?[null,?data]).catch?<
          ????[U,?undefined]?>
          ????((err:?U)?=>?{
          ??????if?(errorExt)?{
          ????????const?parsedError?=?Object.assign({},?err,?errorExt);
          ????????return?[parsedError,?undefined];
          ??????}
          ??????return?[err,?undefined];
          ????}
          )
          ??);
          }
          export?default?to;

          大致流程如下: 函數(shù)to接受參數(shù)PromiseerrorExt,如果這個(gè) Promise 成功時(shí)返回[null, data],如果異常時(shí)會(huì)判斷是否帶有errorExt參數(shù)(代表傳遞給 err 對(duì)象的附加信息),如果有時(shí)會(huì)與 catch 捕獲的 err 合并返回,如果沒(méi)有時(shí)返回[err, undefined]

          很簡(jiǎn)單的邏輯是不是,接著我們看下它的用法:

          • 安裝
                
                #?use?npm
          npm?i?await-to-js?--save
          #?use?yarn
          yarn?add?await-to-js
          • 使用

          首先引入to函數(shù),可以看到包很小,只有 370b,gzip 壓縮后只有 242b,所以放心引入,別擔(dān)心什么包大小問(wèn)題。

          84ae1009cf4a93bbe8ed0ff6e052308a.webpawait-to-js-size.png

          我們通過(guò)to來(lái)改寫(xiě)一下上面第一種問(wèn)題:

                
                import?to?from?'await-to-js';
          //?獲取列表list
          const?[err,?data]?=?await?to(getList(params));
          if?(err)?return;
          //?獲取單個(gè)詳情
          const?info?=?await?to(getListById(list[0]?.id));

          通過(guò)to函數(shù)改造后,如果返回第一個(gè)參數(shù)不為空時(shí),說(shuō)明該請(qǐng)求報(bào)錯(cuò),就可以提前 return 出去,如果不存在第一個(gè)參數(shù)時(shí),則異步請(qǐng)求成功。

          總結(jié)

          本文通過(guò)研究 async/await 的異常捕獲,發(fā)現(xiàn)了兩種常見(jiàn)的異步請(qǐng)求異常捕獲,并提出了兩種簡(jiǎn)單的解決方法。通過(guò)這兩種方法,就可以丟掉冗余的 try-catch,然后你就會(huì)發(fā)現(xiàn)沒(méi)了 try-catch 的代碼看起來(lái)都是順眼的。

          很多小伙伴可能也會(huì)遇到這個(gè)問(wèn)題:盡管你提出了解決方案,但依舊會(huì)有項(xiàng)目組成員不用。你要這么想就錯(cuò)了,自己通過(guò)研究、查資料,最終學(xué)到了東西就足夠了,管別人干嘛!沒(méi)必要啊。

          以上就是本文的全部?jī)?nèi)容,希望這篇文章對(duì)你有所幫助,歡迎點(diǎn)贊和收藏 ??,如果發(fā)現(xiàn)有什么錯(cuò)誤或者更好的解決方案及建議,歡迎隨時(shí)聯(lián)系。

          參考資料

          [1]

          https://es6.ruanyifeng.com/#docs/async#await-%E5%91%BD%E4%BB%A4

          [2]

          https://github.com/scopsy/await-to-js

          [3]

          https://github.com/scopsy/await-to-js/blob/master/src/await-to-js.ts

          關(guān)于本文

          作者:翔子丶https://juejin.cn/post/7224391827654180922

          最后


          歡迎關(guān)注【前端瓶子君】??ヽ(°▽°)ノ? 回復(fù)「 交流 」,吹吹水、聊聊技術(shù)、吐吐槽! 回復(fù)「 閱讀 」,每日刷刷高質(zhì)量好文! 如果這篇文章對(duì)你有幫助,在看」是最大的支持!


                    
                          

          最后不要忘了點(diǎn)贊呦!17c122774ce7f1ce69d790d13612bc92.webp


          瀏覽 54
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本va在线观看 日本va中文字幕 | 日本成人1024 | 在线天堂资源 | 国产色情电影在线观看 | 成人午夜剧场视频网站 |