Appearance
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)参数说明
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
task | Promise<T> | () => T | Promise<T> | 是 | - | 要执行的任务。推荐传函数,这样同步抛错和异步 reject 都能被捕获。 |
loadingRef | Ref<boolean> | null | 否 | - | 可选 loading 状态。传入 Vue ref 时,执行前会设为 true,结束后设为 false。 |
返回值
返回 Promise<{ data: T | null; error: any }>:
| 字段 | 成功时 | 失败时 | 说明 |
|---|---|---|---|
data | 任务结果 | null | 成功结果。 |
error | null | 捕获到的异常 | 失败原因。 |
常用场景
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)
}
}