专栏名称: 程序员大咖
程序员大咖,努力成就期待着的自己。分享程序员技术文章、程序员工具资源、程序员精选课程、程序员视频教程、程序员热点资讯、程序员学习资料等。
目录
相关文章推荐
VC/PE/MA金融圈  ·  减员严重,大家做好准备吧! ·  17 小时前  
湖北药监  ·  资本市场做好金融“五篇大文章” ·  2 天前  
重庆制造  ·  资本市场做好金融“五篇大文章” ·  2 天前  
国际金融报  ·  汇率股指实时播→ ·  2 天前  
金融早实习  ·  华为2025届校园招聘全球启动 ·  3 天前  
51好读  ›  专栏  ›  程序员大咖

async/await 函数到底要不要加 try catch ?

程序员大咖  · 公众号  ·  · 2024-11-03 10:24

正文

前言

写异步函数的时候,promise 和 async 两种方案都非常常见,甚至同一个项目里,不同的开发人员都使用不同的习惯, 不过关于两者的比较不是本文关注的重点,只总结为一句话:“async 是异步编程的终极解决方案”。

当使用 async 函数的时候,很多文章都说建议用 try catch 来捕获异常, 可是实际上我看了很多项目的代码,遵循的并不是严谨,很多都没有用,甚至 catch 函数都没写,这是为什么呢?

我们先看下使用 try catch 情况下的代码示例:

示例1 :使用 try catch

function getUserInfo ({
    return new Promise((resolve, reject) => {
        setTimeout(() => {
                reject('请求异常')
        }, 1000)
    })
}

async function logined ({
    try {
        let userInfo = await getUserInfo()
        // 执行中断
        let pageInfo = await getPageInfo(userInfo?.userId)
    } catch(e) {
        console.warn(e)
    }
}

logined()

执行后会在 catch 里捕获 请求异常 ,然后 getUserInfo 函数中断执行,这是符合逻辑的,对于有依赖关系的接口,中断执行可以避免程序崩溃,这里唯一的问题是 try catch 貌似占据了太多行数,如果每个接口都写的话看起来略显冗余。

示例2:直接 catch

鉴于正常情况下, await 命令后面是一个 Promise 对象, 所以上面代码可以很自然的想到优化方案:

function getUserInfo ({
    return new Promise((resolve, reject) => {
        setTimeout(() => {
                reject('请求异常')
        }, 1000)
    })
}

async function logined ({
    let userInfo = await getUserInfo().catch(e => console.warn(e))
    // 执行没有中断,userInfo 为 undefined
    if (!userInfo) return // 需要做非空校验
    let pageInfo = await getPageInfo(userInfo?.userId)
}

logined()

执行后 catch 可以正常捕获异常,但是程序没有中断,返回值 userInfo undefined , 所以如果这样写的话,就需要对返回值进行非空校验, if (!userInfo) return 我觉得这样有点反逻辑,异常时就应该中断执行才对;

示例3:在 catch 里 reject

可以继续优化,在 catch 里面加一行 return Promise.reject(e) , 可以使 await 中断执行;

完整代码:

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) // 会导致控制台出现 uncaught (in promise) 报错信息
    })
    // 执行中断
    let pageInfo = await getPageInfo(userInfo?.userId)
}

logined()

一般我们在项目里都是用 axios 或者 fetch 之类发送请求,会对其进行一个封装,也可以在里面进行 catch 操作,对错误信息先一步处理,至于是否需要 reject,就看你是否想要在 await 命令异常时候中断了;不使用 reject 则不会中断,但是需要每个接口拿到 response 后先 非空校验, 使用 reject 则会在异常处中断,并且会在控制台暴露 uncaught (in promise) 报错信息。


建议

不需要在 await 处异常时中断,可以这样写,需要做非空校验,控制台不会有报错信息

let userInfo = await getUserInfo().catch(e






请到「今天看啥」查看全文