全新popiart网站 react项目重构
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

35 lines
1.1 KiB

import { useCallback, useState } from "react";
import { Message } from "@arco-design/web-react";
import i18n from "@/i18n";
/**
* 安全执行异步操作:自动 try-catch、loading、错误提示
* @param asyncFn 异步函数
* @returns [执行函数, loading]
*/
export function useSafeAsync<T extends unknown[], R>(
asyncFn: (...args: T) => Promise<R>,
options?: { successMsg?: string; errMsg?: string }
) {
const [loading, setLoading] = useState(false);
const run = useCallback(
async (...args: T): Promise<R | undefined> => {
setLoading(true);
try {
const result = await asyncFn(...args);
if (options?.successMsg) {
Message.success(options.successMsg);
}
return result;
} catch (e) {
const msg = options?.errMsg ?? (e instanceof Error ? e.message : i18n.t("common.operate_failed"));
Message.error(msg);
return undefined;
} finally {
setLoading(false);
}
},
[asyncFn, options?.successMsg, options?.errMsg]
);
return [run, loading] as const;
}