async/await 到底要不要加 try catch?我来给你整明白!
<h1 data-id="heading-0">🧑💻 写在开头</h1><p>点赞 + 收藏 === 学会🤣🤣🤣</p>
<div>
<div>
<h2 data-id="heading-0">前言</h2>
<p>现在写异步代码,基本上就是 <code>Promise</code> 和 <code>async/await</code> 两种写法。虽然这俩都能干同样的活,但 async/await 写起来更像同步代码,读起来更顺眼,所以很多人都说它是"异步编程的终极方案"。</p>
<p>不过有个问题挺让人纠结的:用 async/await 的时候,到底要不要加 try catch 来抓错误?我看了好多项目代码,发现大家做法都不一样,有的加有的不加,甚至有的连 catch 都不写,这就很迷了。</p>
<h2 data-id="heading-1">先看几种写法</h2>
<h3 data-id="heading-2">写法1:老实用 try catch</h3>
</div>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">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()</pre>
</div>
<p>这种写法的好处是错误能抓住,而且代码会在出错的地方停下来,不会继续往下执行。缺点就是 try catch 占了太多行数,每个接口都这么写的话,代码看起来有点啰嗦。</p>
<h3 data-id="heading-3">写法2:直接在后面接 .catch()</h3>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">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()</pre>
</div>
<p>这种写法也能抓住错误,但是程序不会自动停下来,还会继续往下走。所以你得自己检查 <code>userInfo</code> 是不是空的,不然可能会出问题。</p>
<h3 data-id="heading-4">写法3:在 catch 里再 reject</h3>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">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()</pre>
</div>
<div>
<div>
<p>这种写法能让程序在出错的地方停下来,但是会在控制台留下一个 "uncaught (in promise)" 的错误提示,有些人觉得这样不太好看。</p>
<h2 data-id="heading-5">到底该用哪种?</h2>
<p>其实在真实项目里,我们一般会用 axios 或 fetch 这些库来发请求,通常会对它们进行一层封装。在封装的时候就可以统一处理错误了。</p>
<p>至于要不要在 await 后面加 try catch,主要看你想不想让程序在出错的时候停下来:</p>
<ul>
<li>
<p><strong>不想中断程序</strong>,可以这样写:</p>
</li>
</ul>
</div>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">let userInfo = await getUserInfo().catch(e => console.warn(e))
if (!userInfo) return // 记得检查一下是不是空的</pre>
</div>
<p>这样控制台不会报红字错误。</p>
<ul>
<li>想中断程序,又不想看控制台报错,就用 try catch:</li>
</ul>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">try {
let userInfo = await getUserInfo()
let pageInfo = await getPageInfo(userInfo?.userId)
} catch(e) {
console.warn(e)
}
</pre>
</div>
<ul>
<li>想中断程序,又不介意控制台报错:</li>
</ul>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">let userInfo = await getUserInfo().catch(e => {
console.warn(e)
return Promise.reject(e)
})
// 这里会停下来
let pageInfo = await getPageInfo(userInfo?.userId)</pre>
</div>
<div>
<div>
<h2 data-id="heading-6">我的建议</h2>
<p>从我个人的使用体验来看,<strong>try catch 是最好的选择</strong>:</p>
<ul>
<li>代码逻辑更清晰,更像同步代码的写法</li>
<li>错误处理集中在一个地方,好管理</li>
<li>控制台不会出现一堆难看的 "uncaught (in promise)" 错误</li>
<li>符合直觉:出错了就应该停下来</li>
</ul>
<p>虽然 try catch 会让代码多几行,但是比起代码的可读性和可维护性,这点代价是值得的。</p>
<p>既然都已经用 async/await 来写同步风格的代码了,那就干脆用到底,用 try catch 来处理错误,这样代码风格更统一,读起来也更舒服。</p>
</div>
<div>
<h3 id="tid-D8HBxE">如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。</h3>
</div>
<p><em><img src="https://img2024.cnblogs.com/blog/2149129/202501/2149129-20250122165814748-630765389.png" alt="" loading="lazy"></em></p>
</div>
</div>
</div><br><br>
来源:https://www.cnblogs.com/smileZAZ/p/19525458
頁:
[1]