狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

[轉(zhuǎn)帖]async/await 函數(shù)到底要不要加 try catch ?

freeflydom
2023年7月24日 17:17 本文熱度 887

前言

寫異步函數(shù)的時候,promise 和 async 兩種方案都非常常見,甚至同一個項目里,不同的開發(fā)人員都使用不同的習(xí)慣, 不過關(guān)于兩者的比較不是本文關(guān)注的重點(diǎn),只總結(jié)為一句話:“async 是異步編程的終極解決方案”。

當(dāng)使用 async 函數(shù)的時候,很多文章都說建議用 try catch 來捕獲異常, 可是實(shí)際上我看了很多項目的代碼,遵循的并不是嚴(yán)謹(jǐn),很多都沒有用,甚至 catch 函數(shù)都沒寫,這是為什么呢?

我們先看下使用 try catch 情況下的代碼示例:

示例1 :使用 try catch

function getUserInfo () {

    return new Promise((resolve, reject) => {

        setTimeout(() => {

                reject('請求異常')

        }, 1000)

    })

}


async function logined () {

    try {

        let userInfo = await getUserInfo()

        // 執(zhí)行中斷

        let pageInfo = await getPageInfo(userInfo?.userId)

    } catch(e) {

        console.warn(e)

    }

}


logined()


執(zhí)行后會在 catch 里捕獲 請求異常,然后 getUserInfo 函數(shù)中斷執(zhí)行,這是符合邏輯的,對于有依賴關(guān)系的接口,中斷執(zhí)行可以避免程序崩潰,這里唯一的問題是 try catch 貌似占據(jù)了太多行數(shù),如果每個接口都寫的話看起來略顯冗余。

示例2: 直接 catch

鑒于正常情況下,await 命令后面是一個 Promise 對象, 所以上面代碼可以很自然的想到優(yōu)化方案:

function getUserInfo () {

    return new Promise((resolve, reject) => {

        setTimeout(() => {

                reject('請求異常')

        }, 1000)

    })

}


async function logined () {

    let userInfo = await getUserInfo().catch(e => console.warn(e))

    // 執(zhí)行沒有中斷,userInfo 為 undefined

    if (!userInfo) return // 需要做非空校驗

    let pageInfo = await getPageInfo(userInfo?.userId)

}


logined()


執(zhí)行后 catch 可以正常捕獲異常,但是程序沒有中斷,返回值 userInfoundefined, 所以如果這樣寫的話,就需要對返回值進(jìn)行非空校驗,  if (!userInfo) return 我覺得這樣有點(diǎn)反邏輯,異常時就應(yīng)該中斷執(zhí)行才對;

示例3:在 catch  里 reject

可以繼續(xù)優(yōu)化,在 catch 里面加一行 return Promise.reject(e), 可以使 await 中斷執(zhí)行;

完整代碼:

function getUserInfo () {

    return new Promise((resolve, reject) => {

        setTimeout(() => {

            reject('請求異常')

        }, 1000)

    })

}


async function logined () {

    let userInfo = await getUserInfo().catch(e => {

        console.warn(e)

        return Promise.reject(e) // 會導(dǎo)致控制臺出現(xiàn) uncaught (in promise) 報錯信息

    })

    // 執(zhí)行中斷

    let pageInfo = await getPageInfo(userInfo?.userId)

}


logined()


一般我們在項目里都是用 axios 或者 fetch 之類發(fā)送請求,會對其進(jìn)行一個封裝,也可以在里面進(jìn)行 catch 操作,對錯誤信息先一步處理,至于是否需要 reject,就看你是否想要在 await 命令異常時候中斷了;不使用 reject 則不會中斷,但是需要每個接口拿到 response 后先 非空校驗, 使用 reject 則會在異常處中斷,并且會在控制臺暴露  uncaught (in promise)  報錯信息。

建議

不需要在 await 處異常時中斷,可以這樣寫,需要做非空校驗,控制臺不會有報錯信息

let userInfo = await getUserInfo().catch(e => console.warn(e))

if (!userInfo) return



需要在 await 處異常時中斷,并且在意控制臺報錯,可以這樣寫

try {

    let userInfo = await getUserInfo()

    // 執(zhí)行中斷

    let pageInfo = await getPageInfo(userInfo?.userId)

} catch(e) {

    console.warn(e)

}


需要在 await 處異常時中斷,但是不在意控制臺報錯,則可以這樣寫

let userInfo = await getUserInfo().catch(e => {

    console.warn(e)

    return Promise.reject(e) // 會導(dǎo)致控制臺出現(xiàn) uncaught (in promise) 報錯信息

})

// 執(zhí)行中斷

let pageInfo = await getPageInfo(userInfo?.userId)


總結(jié)

幾種寫法,初看可能覺得第三種 catch 這種寫法是最好的,但是細(xì)想下,從用戶體驗上來看,我覺得 try catch 是最好的,邏輯直觀、符合同步編程思維,控制臺不會暴露 uncaught (in promise) 報錯信息;

而鏈?zhǔn)秸{(diào)用的 catch (里面再 reject),是傳統(tǒng) promise 的回調(diào)寫法,既然已經(jīng)用 async await 這種同步編程寫法了,再用 catch 鏈?zhǔn)綄懛ǎ杏X沒必要。


原文鏈接



該文章在 2023/7/24 17:17:44 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊、財務(wù)費(fèi)用、相關(guān)報表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved