稀土掘金技术社区

我删光了项目里的 try-catch,老板:6

相信我们经常这样写bug(不是 👇:
image_90.gif

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(linetry {  const res = await api.getUser()  console.log('✅ 用户信息', res)} catch (err) {  console.error('❌ 请求失败', err)}

看似没问题

  • 每个接口都要 try-catch,太啰嗦了!
  • 错误处理逻辑分散,不可控!
  • 代码又臭又长💨!

💡 目标:「不抛异常的安全请求封装」

我们希望实现这样的调用👇:

ounter(lineounter(lineounter(lineounter(lineconst [err, data] = await safeRequest(api.getUser(1))if (err) return showError(err)console.log('✅ 用户信息:', data)

是不是清爽多了?✨
没有 try-catch,却能同时拿到错误和数据。


🧩 实现步骤

1️⃣ 先封装 Axios 实例

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line// src/utils/request.jsimport axios from 'axios'import { ElMessage } from 'element-plus'
const service = axios.create({  baseURL: import.meta.env.VITE_API_BASE_URL,  timeout: 10000,})
// 🧱 请求拦截器service.interceptors.request.use(  (config) => {    const token = localStorage.getItem('token')    if (token) config.headers.Authorization = `Bearer ${token}`    return config  },  (error) => Promise.reject(error))
// 🧱 响应拦截器service.interceptors.response.use(  (response) => {    const res = response.data    if (res.code !== 0) {      ElMessage.error(res.message || '请求失败')      return Promise.reject(new Error(res.message || '请求失败'))    }    return res.data  },  (error) => {    ElMessage.error(error.message || '网络错误')    return Promise.reject(error)  })
export default service

拦截器的作用:

  • ✅ 统一处理 token;
  • ✅ 统一处理错误提示;
  • ✅ 保证业务层拿到的永远是“干净的数据”。

2️⃣ 封装一个「安全请求函数」

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line// src/utils/safeRequest.jsexport async function safeRequest(promise) {  try {    const data = await promise    return [null, data] // ✅ 成功时返回 [null, data]  } catch (err) {    return [err, null] // ❌ 失败时返回 [err, null]  }}

这就是关键!
它让所有 Promise 都变得「温柔」——不再抛出异常,而是返回结构化结果。


3️⃣ 封装 API 模块

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line// src/api/user.jsimport request from '@/utils/request'
export const userApi = {  getUser(id) {    return request.get(`/user/${id}`)  },  updateUser(data) {    return request.put('/user', data)  },}

4️⃣ 在业务层优雅调用

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line<scriptsetup>import { ref, onMounted } from 'vue'import { userApi } from '@/api/user'import { safeRequest } from '@/utils/safeRequest'
const user = ref(null)
onMounted(async () => {  const [err, data] = await safeRequest(userApi.getUser(1))  if (err) return showError(err)  console.log('✅ 用户信息:', data)})</script>

是不是很优雅、数据逻辑清晰、不需要 try-catch、 错误不崩溃。

「老板说:牛🍺,你小子有点东西」

🧱 我们还可以进一步优化:实现自动错误提示

我们可以给 safeRequest 增加一个选项,让错误自动提示:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line// src/utils/safeRequest.jsimport { ElMessage } from 'element-plus'
export async function safeRequest(promise, { showError = true } = {}) {  try {    const data = await promise    return [null, data]  } catch (err) {    if (showError) {      ElMessage.error(err.message || '请求失败')    }    return [err, null]  }}

使用时👇:

ounter(lineconst [err, data] = await safeRequest(userApi.getUser(1), { showError: false })

这样你可以灵活控制是否弹出错误提示,
比如某些静默请求就可以关闭提示。


🧠 进阶:TypeScript 支持(超丝滑)

如果你用的是 TypeScript,可以让返回类型更智能👇:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineexport async function safeRequest<T>(  promise: Promise<T>): Promise<[Error | null, T | null]> {  try {    const data = await promise    return [null, data]  } catch (err) {    return [err as Error, null]  }}

调用时:

ounter(lineounter(lineconst [err, user] = await safeRequest<User>(userApi.getUser(1))if (user) console.log(user.name) // ✅ 自动提示类型

老板:写得很好,下次多写点,明天你来当老板!

图片
点击"阅读原文"了解详情~