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

news/2024/9/30 16:56:07

前言

写异步函数的时候,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 可以正常捕获异常,但是程序没有中断,返回值 userInfoundefined, 所以如果这样写的话,就需要对返回值进行非空校验, 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 => console.warn(e))
if (!userInfo) return

需要在 await 处异常时中断,并且在意控制台报错,可以这样写

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

总结

几种写法,初看可能觉得第三种 catch 这种写法是最好的,但是细想下,从用户体验上来看,我觉得 try catch 是最好的,逻辑直观、符合同步编程思维,控制台不会暴露 uncaught (in promise) 报错信息;

而链式调用的 catch (里面再 reject),是传统 promise 的回调写法,既然已经用 async await 这种同步编程写法了,再用 catch 链式写法,感觉没必要。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/66557.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

UOS 1070/Deepin 23环境下安装Master PDF Editor 5.8.35

UOS 1070/Deepin 23环境下安装Master PDF Editor 5.8.35在UOS 1070环境下,有福昕PDF编辑器可以使用,但是升级到Deepin v23之后,福昕编辑器就无法安装了,需要换工具。 比较好用的就是Master PDF Editor,安装注册也非常简单,现在写到这里,作为记录。# 目前最方便安装的是m…

深度学习系列之1----直观解释Transformer

Abstract 这个系列主要用来记录我自己这种的AI小白的学习之路,通过将所学所知总结下来,记录下来。之前总喜欢记录在笔记本上,或者ipad上,或者PC端的Typora上,但总是很难回头检索到一些系统的知识,因此我觉得博客是一个不错的选择,因为时不时我就会登录网站翻看过去的痕迹…

chrome-截图录屏插件-Awesome Screenshot

💖简介 Awesome Screenshot 截图录屏是一款浏览器扩展程序,它可以帮助用户进行网页截图、编辑图片以及录制屏幕视频 📖版本 4.4.22 🌟功能截图:可以截取整个网页(即使是需要滚动才能看到的部分)、可见部分或者选定区域。 编辑:截图后可以直接在浏览器中对图片进行编…

PARTI-Oracle关系数据结构-表和表簇

2. 表和表簇 2.1. 模式对象简介 数据库模式是数据结构的逻辑容器,这些数据结构称为模式对象。模式对象的例子有表和索引。模式对象是通过 SQL 创建和操作的。 一个数据库用户拥有密码和各种数据库权限。每个用户拥有一个与其同名的模式。模式包含了属于该用户的数据。例如,hr…

Python - [05] 爬虫

题记部分 001 || 爬虫的工作原理(1)获取数据。爬虫程序会根据提供的网址,向服务器发起请求,然后返回数据。 (2)解析数据。爬虫程序会把服务器返回的数据解析成我们能读懂的格式。 (3)提取数据。爬虫程序再从中提取出我们需要的数据。 (4)储存数据。爬虫程序把这些有…

(三)Style样式

一:定义样式作用于按钮<Window x:Class="WpfTest.WindowStyle"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/ex…

20240930模拟赛

T1连珠风暴 (necklace.pas/c/cpp) 问题描述:给定M种颜色的珠子,每种颜色珠子的个数均不限,将这些珠子做成长度为N的项链。 问能做成多少种不重复的项链. 并且两条项链相同,当且仅当两条项链通过旋转或是翻转后能重合在一起,且对应珠子的颜色相同。样例输入:2 5样例输出…

9.23 ~ 9.30

集训9.23 集训第一天。 早晨因为太多人没拿早读资料被老登 D 了。 不是哥们你不早说 现在我上哪给你找资料去 😅 上午模拟赛。 发现 T1 的图挂了,于是看形式化题意;初始有一张 \(n\) 个点的完全图,接着删除 \(m\) 条边。 询问有多少长度为 \(13\) 的序列 \(p_1,...,p_{13}…