🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付

我刪光了專案裡的 try-catch,老闆:6

相信我們經常這樣寫 bug(不是 👇:

image_90.gif

try {
  const res = await api.getUser()
  console.log('✅ 使用者資訊', res)
} catch (err) {
  console.error('❌ 請求失敗', err)
}

看似沒問題

  • 每個介面都要 try-catch,太囉嗦了!
  • 錯誤處理邏輯分散,不可控!
  • 代碼又臭又長💨!

image_432.gif

💡 目標:不拋異常的安全請求封裝

我們希望實現這樣的調用👇:

const [err, data] = await safeRequest(api.getUser(1))
if (err) return showError(err)
console.log('✅ 使用者資訊:', data)

是不是清爽多了?✨
沒有 try-catch,卻能同時拿到錯誤和數據。


🧩 實現步驟

1️⃣ 先封裝 Axios 實例

// 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️⃣ 封裝一個「安全請求函數」

// 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 模組

// 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️⃣ 在業務層優雅調用

<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) return showError(err)
  console.log('✅ 使用者資訊:', data)
})
</script>

是不是很優雅、數據邏輯清晰、不需要 try-catch、 錯誤不崩潰。

老闆說:牛🍺,你小子有點東西

image_443.gif

🧱 我們還可以進一步優化:實現自動錯誤提示

我們可以給 safeRequest 增加一個選項,讓錯誤自動提示:

// 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]
  }
}

使用時👇:

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

這樣你可以靈活控制是否彈出錯誤提示,
比如某些靜默請求就可以關閉提示。


🧠 進階:TypeScript 支援(超絲滑)

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

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]
  }
}

調用時:

const [err, user] = await safeRequest<User>(userApi.getUser(1))
if (user) console.log(user.name) // ✅ 自動提示類型

老闆:寫得很好,下次多寫點,明天你來當老闆


原文出處:https://juejin.cn/post/7565811094734389248


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝28   💬4   ❤️7
840
🥈
我愛JS
📝2   💬8   ❤️2
113
🥉
御魂
💬1  
4
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付