Redian新闻
>
async/await 函数到底要不要加 try catch ?

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

公众号新闻

推荐关注↓

作者:Ethan_Zhou

https://juejin.cn/post/7213362932423376933

前言

写异步函数的时候,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 链式写法,感觉没必要。


- EOF -

推荐阅读  点击标题可跳转

1、Google 有一个函数,20000 个变量……

2、员工每天“带薪如厕”3~6小时被开,官司一直打到高院

3、已刑拘!人大毕业生盗取学生信息建“颜值打分”网站


关注「程序员的那些事」加星标,不错过圈内事

点赞和在看就是最大的支持❤️

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
在加拿大私人停车场罚单到底要不要付?华人小哥:吃人不吐骨头,我刚付完钱就收到罚单!𝐂𝐚𝐥𝐧𝐢𝐊𝐞𝐚𝐧双皮奶内衣裤,软弹有度,上身0束缚~马里兰州-​The Bryn Mawr School 布林茅尔女校In China, Pet Psychics and Their True Believers三十九 高级社Lenovo Legion 5 Pro 16in 165Hz QHD IPS NVIDIA G-SYNC R7-5800H 16大连这座城市为何留不住最好的学生了?转孩子到底要不要枕枕头?Node 中的 AsyncLocalStorage 的前世今生和未来大语文时代,到底要不要让孩子学国学咀外文嚼汉字(251)挥杆“虎巻”​孩子湿疹到底要不要忌口?恭喜客人一周内拿到新护照!需要加急更新护照吗?需要加急公证认证吗?想加急找美之信旅游!巴黎市长将重修Châtelet 广场以方便行人独家对话苹果技术副总裁 Kevin Lynch:Apple Watch 如何在方寸之间雕花?沙发到底要不要靠墙?看完恍然大悟!【装修干货】在伦敦想要不合租,年薪到底要多少?来看看你达标没!富国阿联酋的寒酸王宫衰老是可以逆转的吗?2020年《自然》杂志封面文章,题目:Turning Back Time(时光倒流)Biological Psychiatry | 浙江大学李晓明团队揭示大脑不同的应对策略Logitech G815 Lightsync RGB(one back foot missing)LG 27'' UltraGear QHD IPS 1ms 144Hz HDR Monitor with G-SYNC Comp对线面试官:synchronized 到底能不能禁止指令重排序?中国的盐,够吃多少年?到底要不要囤盐?【城事】巴黎市长将重修Châtelet 广场以方便行人Logitech G G512 CARBON LIGHTSYNC RGB Mechanical Gaming Keyboard Large函数还可以这样玩?这个90%的人不知道的统计函数也太牛了!AMD 提交 FreeSync Panel Replay 技术,可令锐龙笔记本在屏幕内容不变时降低功耗【𝐂𝐚𝐥𝐧𝐢𝐊𝐞𝐚𝐧双皮奶无痕内裤】49元三条!巨巨巨好穿 !!简直就是辣妹顶配,食品级冰箱收纳盒【一日团】Shayne 离开 HBA,Shayne Boy 懂哥们却更爱买了Biological Psychiatry | 仇子龙/李斐团队合作发现9个中国人群孤独症候选基因并揭示高功能孤独症的遗传特性你到底要不要脸​半导体行业的终端市场疲软,Synopsys该如何破局?Asus ROG Strix XG276Q 27" FHD 170Hz 1ms G-Sync Gaming Monitor开源 Java 性能分析器比较:VisualVM、JMC 和 async-profiler
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。