async/await 到底要不要加 try catch?我来给你整明白!

前言

现在写异步代码,基本上就是 Promiseasync/await 两种写法。虽然这俩都能干同样的活,但 async/await 写起来更像同步代码,读起来更顺眼,所以很多人都说它是"异步编程的终极方案"。

不过有个问题挺让人纠结的:用 async/await 的时候,到底要不要加 try catch 来抓错误?我看了好多项目代码,发现大家做法都不一样,有的加有的不加,甚至有的连 catch 都不写,这就很迷了。

先看几种写法

写法1:老实用 try catch

javascript 复制代码
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()

这种写法的好处是错误能抓住,而且代码会在出错的地方停下来,不会继续往下执行。缺点就是 try catch 占了太多行数,每个接口都这么写的话,代码看起来有点啰嗦。

写法2:直接在后面接 .catch()

javascript 复制代码
function getUserInfo () {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('请求出错了哦')
        }, 1000)
    })
}

async function logined () {
    let userInfo = await getUserInfo().catch(e => console.warn('抓到一个错误:', e))
    // 注意:这里即使出错了也会继续执行!
    if (!userInfo) return // 所以得手动检查一下
    let pageInfo = await getPageInfo(userInfo?.userId)
}

logined()

这种写法也能抓住错误,但是程序不会自动停下来,还会继续往下走。所以你得自己检查 userInfo 是不是空的,不然可能会出问题。

写法3:在 catch 里再 reject

javascript 复制代码
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) // 这里再扔出去一次
    })
    // 这样就会停在这里了
    let pageInfo = await getPageInfo(userInfo?.userId)
}

logined()

这种写法能让程序在出错的地方停下来,但是会在控制台留下一个 "uncaught (in promise)" 的错误提示,有些人觉得这样不太好看。

到底该用哪种?

其实在真实项目里,我们一般会用 axios 或 fetch 这些库来发请求,通常会对它们进行一层封装。在封装的时候就可以统一处理错误了。

至于要不要在 await 后面加 try catch,主要看你想不想让程序在出错的时候停下来:

  1. 不想中断程序,可以这样写:

    javascript 复制代码
    let userInfo = await getUserInfo().catch(e => console.warn(e))
    if (!userInfo) return // 记得检查一下是不是空的

    这样控制台不会报红字错误。

  2. 想中断程序,又不想看控制台报错,就用 try catch:

    javascript 复制代码
    try {
        let userInfo = await getUserInfo()
        let pageInfo = await getPageInfo(userInfo?.userId)
    } catch(e) {
        console.warn(e)
    }
  3. 想中断程序,又不介意控制台报错:

    javascript 复制代码
    let userInfo = await getUserInfo().catch(e => {
        console.warn(e)
        return Promise.reject(e)
    })
    // 这里会停下来
    let pageInfo = await getPageInfo(userInfo?.userId)

我的建议

从我个人的使用体验来看,try catch 是最好的选择

  • 代码逻辑更清晰,更像同步代码的写法
  • 错误处理集中在一个地方,好管理
  • 控制台不会出现一堆难看的 "uncaught (in promise)" 错误
  • 符合直觉:出错了就应该停下来

虽然 try catch 会让代码多几行,但是比起代码的可读性和可维护性,这点代价是值得的。

既然都已经用 async/await 来写同步风格的代码了,那就干脆用到底,用 try catch 来处理错误,这样代码风格更统一,读起来也更舒服。

相关推荐
Hilaku37 分钟前
我用 Gemini 3 Pro 手搓了一个并发邮件群发神器(附源码)
前端·javascript·github
IT_陈寒38 分钟前
Java性能调优实战:5个被低估却提升30%效率的JVM参数
前端·人工智能·后端
快手技术39 分钟前
AAAI 2026|全面发力!快手斩获 3 篇 Oral,12 篇论文入选!
前端·后端·算法
颜酱41 分钟前
前端算法必备:滑动窗口从入门到很熟练(最长/最短/计数三大类型)
前端·后端·算法
全栈前端老曹1 小时前
【包管理】npm init 项目名后底层发生了什么的完整逻辑
前端·javascript·npm·node.js·json·包管理·底层原理
HHHHHY1 小时前
mathjs简单实现一个数学计算公式及校验组件
前端·javascript·vue.js
boooooooom1 小时前
Vue3 provide/inject 跨层级通信:最佳实践与避坑指南
前端·vue.js
一颗烂土豆1 小时前
Vue 3 + Three.js 打造轻量级 3D 图表库 —— chart3
前端·vue.js·数据可视化
青莲8431 小时前
Android 动画机制完整详解
android·前端·面试
iReachers1 小时前
HTML打包APK(安卓APP)中下载功能常见问题和详细介绍
前端·javascript·html·html打包apk·网页打包app·下载功能