在前端开发里,很多人第一次接触 try...catch,往往只是知道"它能捕获报错",但真正写业务代码时,还是容易出现这些问题:
- 不知道什么时候该用
try...catch - 不知道
try...catch和then().catch()有什么区别 - 分不清"业务失败"和"代码异常"
这篇文章就专门讲清楚:try...catch 在前端项目中到底该怎么用。
一、try...catch 是什么
try...catch 是 JavaScript 中用来处理异常的一种语法结构。
基本写法如下:
js
try {
// 可能出错的代码
} catch (error) {
// 出错后执行的代码
}
如果你还想在最后做统一收尾,可以加上 finally:
js
try {
// 可能出错的代码
} catch (error) {
// 错误处理
} finally {
// 不管是否出错,都会执行
}
可以这样理解:
try:尝试执行catch:捕获异常finally:最后收尾
二、前端开发中为什么需要 try...catch
因为在真实业务里,很多代码并不是一定安全的。
比如这些场景都可能报错:
- 接口请求失败
- 网络超时
- JSON 解析失败
- 第三方方法执行异常
- 某些变量为空导致调用出错
- 手动抛出的业务异常
如果没有处理,轻则当前逻辑中断,重则页面直接报错、用户体验变差。
所以,try...catch 的核心价值就是:
当代码发生异常时,不让程序直接崩掉,而是由我们自己决定怎么处理。
三、最常见的使用场景:async/await 接口请求
这是前端里最典型的应用场景。
示例
js
async function getList() {
try {
const res = await fetchList()
console.log(res)
} catch (error) {
console.log('请求失败')
}
}
为什么这里适合用 try...catch?
因为 await 等待的 Promise 一旦失败,就会直接抛错。
这时候如果没有 catch,代码就会中断。
所以在接口请求中,try...catch 通常用来处理:
- 网络异常
- 请求超时
- 服务端错误
- 请求被拦截器 reject
四、try...catch 最标准的请求写法
在前端项目里,一个比较推荐的结构是:
js
async function getList() {
this.loading = true
try {
const res = await fetchList()
if (res.code === 200) {
this.tableData = res.rows
} else {
this.$message.error(res.msg)
}
} catch (error) {
this.$message.error('请求异常')
} finally {
this.loading = false
}
}
这段代码里每一部分职责都很清楚:
try:处理正常请求流程if/else:处理业务成功或失败catch:处理真正的异常finally:关闭loading,做统一收尾
这也是项目中最值得养成的写法之一。
五、catch 捕获的到底是什么
这里有一个很容易混淆的点:
catch 捕获的是异常,不是所有失败结果。
比如下面这种情况:
js
const res = await fetchList()
if (res.code !== 200) {
this.$message.error(res.msg)
}
这里 res.code !== 200 并不是异常,它只是接口返回了一个"业务失败"的结果。
这类情况应该用 if/else 判断,而不是交给 catch。
真正会进入 catch 的情况通常是:
- 请求 Promise 被 reject
- 代码运行时报错
- 手动
throw new Error() JSON.parse()解析失败- 某个对象不存在还继续调用它的方法
所以你可以这样记:
if/else处理业务状态catch处理程序异常
六、为什么 loading 要放在 finally
很多人会这样写:
js
async function getList() {
this.loading = true
const res = await fetchList()
this.loading = false
}
这段代码看起来没问题,但其实有风险。
如果请求报错了,await fetchList() 后面的代码根本不会执行,结果就是:
loading一直不关闭- 页面一直处于加载状态
这就是为什么更推荐这样写:
js
async function getList() {
this.loading = true
try {
const res = await fetchList()
} catch (error) {
console.log(error)
} finally {
this.loading = false
}
}
finally 的特点是:
不管成功还是失败,它都会执行。
因此非常适合放这些"收尾动作":
- 关闭
loading - 按钮恢复可点击
- 弹层关闭处理
- 状态重置
一句话总结:
只要是异步流程结束后一定要做的事,就优先放在 finally。
七、除了请求,哪些地方也适合用 try...catch
1. JSON 解析
js
try {
const data = JSON.parse(str)
} catch (error) {
console.log('JSON 格式错误')
}
因为 JSON.parse() 一旦格式不合法,就会直接抛错。
2. 本地缓存读取后转换
js
try {
const userInfo = JSON.parse(localStorage.getItem('userInfo'))
} catch (error) {
console.log('本地缓存数据异常')
}
如果本地数据被污染或者格式错误,这里就很适合兜底。
3. 第三方库调用
js
try {
somePlugin.init()
} catch (error) {
console.log('插件初始化失败')
}
第三方方法很多时候你无法完全保证稳定性,这时候可以用 try...catch 做保护。
4. 手动校验并主动抛错
js
try {
if (!formData.name) {
throw new Error('名称不能为空')
}
} catch (error) {
console.log(error.message)
}
这类写法在一些复杂逻辑校验里也会用到。
八、什么时候不需要用 try...catch
虽然它很好用,但也不能滥用。
1. 普通条件判断不需要
js
if (res.code === 200) {
...
}
这类属于正常业务判断,不是异常。
2. 简单赋值不需要
js
this.name = 'test'
这种代码没有必要包一层 try...catch。
3. 已经有 .catch() 处理时,不一定要再套一层
js
fetchList()
.then(res => {
...
})
.catch(err => {
...
})
这种写法本身已经在处理异常了,没必要再重复包一层。
九、try...catch 和 .then().catch() 的区别
很多人会问:既然 Promise 本身也有 .catch(),为什么还要用 try...catch?
其实两者都能处理异常,但风格不同。
.then().catch() 写法
js
fetchList()
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
async/await + try...catch 写法
js
try {
const res = await fetchList()
console.log(res)
} catch (err) {
console.log(err)
}
区别在于:
.then().catch()更偏 Promise 链式风格try...catch更像同步代码,可读性更强- 逻辑复杂时,
try...catch往往更清晰
所以在业务开发中,尤其是一个方法里有多步异步操作时,很多人更倾向于用 async/await + try...catch。
十、使用 try...catch 的几个建议
1. 不要把所有代码都塞进 try
try 里只放可能抛错的核心逻辑,别把无关代码全包进去。
2. catch 不要只写空代码
错误被捕获之后,最好至少做一件事:
- 打印日志
- 给出提示
- 返回默认值
- 终止后续操作
3. 收尾逻辑放 finally
像 loading = false 这种代码,优先放进 finally。
4. 分清业务失败和程序异常
这一点特别重要:
- 业务失败用
if/else - 程序异常用
catch
十一、推荐模板
如果你平时写的是接口请求,这里给你一个非常实用的模板:
js
async function loadData() {
this.loading = true
try {
const res = await fetchData()
if (res.code === 200) {
this.list = res.data
} else {
this.$message.error(res.msg || '操作失败')
}
} catch (error) {
this.$message.error('请求异常')
console.error(error)
} finally {
this.loading = false
}
}
这套结构基本可以覆盖大多数前端请求场景。
十二、总结
try...catch 并不复杂,但它在前端项目里非常重要。
你只需要记住这几点:
try用来放可能报错的代码catch用来处理异常finally用来做统一收尾if/else处理业务状态,不要和catch混用- 在
async/await请求中,try...catch是最常见也最推荐的写法