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

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

js 复制代码
try {
  const res = await api.getUser()
  console.log('✅ 用户信息', res)
} catch (err) {
  console.error('❌ 请求失败', err)
}

看似没问题

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

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

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

js 复制代码
const [err, data] = await safeRequest(api.getUser(1))

if (err) {
  console.warn('❌ 获取用户失败:', err.message)
} else {
  console.log('✅ 用户信息:', data)
}

是不是清爽多了?✨

没有 try-catch,却能同时拿到错误和数据。


🧩 实现步骤

1️⃣ 先封装 Axios 实例

js 复制代码
// src/utils/request.js
import 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️⃣ 封装一个「安全请求函数」

js 复制代码
// src/utils/safeRequest.js
export async function safeRequest(promise) {
  try {
    const data = await promise
    return [null, data] // ✅ 成功时返回 [null, data]
  } catch (err) {
    return [err, null] // ❌ 失败时返回 [err, null]
  }
}

这就是关键!

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


3️⃣ 封装 API 模块

js 复制代码
// src/api/user.js
import request from '@/utils/request'

export const userApi = {
  getUser(id) {
    return request.get(`/user/${id}`)
  },
  updateUser(data) {
    return request.put('/user', data)
  },
}

4️⃣ 在业务层优雅调用

vue 复制代码
<script setup>
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) {
    console.warn('❌ 获取用户失败:', err.message)
  } else {
    user.value = data
  }
})
</script>

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

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

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

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

js 复制代码
// src/utils/safeRequest.js
import { 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]
  }
}

使用时👇:

js 复制代码
const [err, data] = await safeRequest(userApi.getUser(1), { showError: false })

这样你可以灵活控制是否弹出错误提示,

比如某些静默请求就可以关闭提示。


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

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

ts 复制代码
export 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]
  }
}

调用时:

ts 复制代码
const [err, user] = await safeRequest<User>(userApi.getUser(1))
if (user) console.log(user.name) // ✅ 自动提示类型

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

有27届前端仔要实习的可以来看看广州双休小工厂:juejin.cn/post/756520...

相关推荐
程序猿阿伟37 分钟前
《Chrome标签组搭建多任务高效浏览指南》
前端·chrome
2601_958352901 小时前
双麦 DSP 音频模块实战:一文梳理 A-68 在全行业场景的声学解决方案与落地要点
前端·嵌入式硬件·音视频·语音识别·降噪消回音·音频处理模块
智码看视界1 小时前
老梁聊全栈:JavaScript 原型链深入探索对象继承的奥秘
前端·javascript·ecmascript
布朗克1681 小时前
39 Spring Boot Web实战
前端·spring boot·后端·实战
纽格立科技1 小时前
DRM 发射端链路图(上)
前端·人工智能·车载系统·信息与通信·传媒
一 乐2 小时前
幼儿园管理系统|基于springboot + vue幼儿园管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·幼儿园管理系统
云水一下2 小时前
Vue.js从零到精通系列(七):高级特性实战——Teleport、异步组件、自定义指令与TypeScript深度结合
前端·vue.js·typescript
qq4356947012 小时前
Vue05
前端·vue.js
qq_422152572 小时前
PDF 解密工具怎么选?2026 年文档密码移除方案与注意事项
java·前端·pdf
YHHLAI2 小时前
前端工程化调用 AI 多模态生图模型:Qwen Image Demo 实战
前端·人工智能