Skip to content
On this page

tryCatch方法

Hidden Title

基础用法:await tryCatch(() => task())

基础用法

说明

tryCatch 用于统一处理同步 throw 和异步 reject,避免每个接口或任务都手写 try...catch。它会返回固定的 { data, error } 结构,并可自动维护一个 Vue ref 类型的 loading 状态。

调用形式

ts
await tryCatch(promise)
await tryCatch(() => task())
await tryCatch(() => task(), loadingRef)
await tryCatch(promise)
await tryCatch(() => task())
await tryCatch(() => task(), loadingRef)

参数说明

参数类型必填默认值说明
taskPromise<T> | () => T | Promise<T>-要执行的任务。推荐传函数,这样同步抛错和异步 reject 都能被捕获。
loadingRefRef<boolean> | null-可选 loading 状态。传入 Vue ref 时,执行前会设为 true,结束后设为 false

返回值

返回 Promise<{ data: T | null; error: any }>

字段成功时失败时说明
data任务结果null成功结果。
errornull捕获到的异常失败原因。

常用场景

ts
const loading = ref(false)

const { data, error } = await tryCatch(() => fetchUser(), loading)
if (error) {
  $toast(error.message, 'e')
}

const result = await tryCatch(Promise.resolve({ id: 1 }))
const loading = ref(false)

const { data, error } = await tryCatch(() => fetchUser(), loading)
if (error) {
  $toast(error.message, 'e')
}

const result = await tryCatch(Promise.resolve({ id: 1 }))

注意事项

优先传 () => task(),这样函数执行阶段的同步错误也能被捕获。如果第二个参数不是 ref,函数不会直接修改它,并会在控制台提示无法修改非 ref 的 loading。

函数源码

tryCatch

来源:packages/utils/src/base.ts

/**
 * 统一处理 Promise 或任务函数执行结果。
 *
 * 推荐优先传入函数,这样可以同时捕获同步 `throw` 和异步 `reject`。
 *
 * @param task Promise,或返回值 / Promise 的函数。
 * @param sendLoading 可选的 loading `ref`。
 * @returns 包含 `data` 和 `error` 的结果对象。
 *
 * @example
 * const loading = ref(false)
 * const { data, error } = await tryCatch(() => fetchUserData(), loading)
 *
 * @example
 * const { data, error } = await tryCatch(Promise.resolve({ id: 1 }))
 *
 * @example
 * const { data, error } = await tryCatch(() => {
 *   if (!form.name) throw new Error('请输入名称')
 *   return submitForm(form)
 * })
 */
export function tryCatch<T>(task: Promise<T>, sendLoading?: Ref<boolean> | null): Promise<TryCatchResult<T>>
export function tryCatch<T>(task: () => T | Promise<T>, sendLoading?: Ref<boolean> | null): Promise<TryCatchResult<T>>
export async function tryCatch<T>(
  task: TryCatchTask<T>,
  sendLoading?: Ref<boolean> | null,
): Promise<TryCatchResult<T>> {
  const updateLoading = (value: boolean): void => {
    if (isRef(sendLoading)) {
      sendLoading.value = value
    } else if (sendLoading !== undefined && sendLoading !== null) {
      consola.warn('Cannot modify non-ref sendLoading directly!')
    }
  }

  updateLoading(true)

  try {
    const data = typeof task === 'function' ? await task() : await task
    return { data, error: null }
  } catch (error: any) {
    return { data: null, error }
  } finally {
    updateLoading(false)
  }
}

思云博智私有前端组件库