diff --git a/src/request.ts b/src/request.ts index e1d3e7a..9f0014a 100644 --- a/src/request.ts +++ b/src/request.ts @@ -51,6 +51,10 @@ export type RequestDispatcher = ( ...args: Parameters ) => Canceler; +export type RequestAsyncFunc = ( + ...args: Parameters +) => Promise, Payload]>; + /** * Normalize the error response returned from `@axios-use/vue` */ diff --git a/src/useResource.ts b/src/useResource.ts index 84560fa..ece032e 100644 --- a/src/useResource.ts +++ b/src/useResource.ts @@ -8,6 +8,7 @@ import type { BodyData, RequestError, Request, + RequestAsyncFunc, RequestDispatcher, RequestCallbackFn, } from "./request"; @@ -29,25 +30,27 @@ export type UseResourceResultState = ComputedRef< RequestState >; -export type UseResourceResult = [ +export type UseResourceResult = [ /** Response data group */ UseResourceResultState, /** A function that enables you to re-execute the request. And pass in new variables */ - RequestDispatcher, + A extends true ? RequestAsyncFunc : RequestDispatcher, /** A function that enables you to re-execute the request. Keep the latest variables */ () => Canceler | undefined, /** A function that cancel the request */ Canceler, ]; -export type UseResourceOptions = Pick< - RequestConfigType, - "instance" | "getResponseItem" -> & +export type UseResourceOptions< + T extends Request, + A extends boolean = false, +> = Pick & RequestCallbackFn & { /** Conditional Fetching */ filter?: (...args: Parameters) => boolean; defaultState?: RequestState; + /** Control the return value of the request */ + asyncReq?: A; }; function getDefaultStateLoading( @@ -87,11 +90,11 @@ export type RequestDepsParameters = | FullRefArrayItem> | ComputedRef>; -export function useResource( +export function useResource( fn: T, requestParams?: RequestDepsParameters | false, - options?: UseResourceOptions, -): UseResourceResult { + options?: UseResourceOptions, +): UseResourceResult { const [createRequest, { clear }] = useRequest(fn, { onCompleted: options?.onCompleted, onError: options?.onError, @@ -107,7 +110,7 @@ export function useResource( ...options?.defaultState, }); - const request = (...args: Parameters) => { + const _reqDispatcher = (...args: Parameters) => { clear(REQUEST_CLEAR_MESSAGE); const { ready, cancel } = createRequest(...args); @@ -126,6 +129,26 @@ export function useResource( return cancel; }; + const _reqAsync = async (...args: Parameters) => { + clear(REQUEST_CLEAR_MESSAGE); + + const { ready } = createRequest(...args); + + try { + dispatch({ type: "start" }); + const [data, response] = await ready(); + dispatch({ type: "success", data, response }); + return [data, response]; + } catch (e) { + const error = e as RequestError, BodyData>; + if (!error.isCancel) { + dispatch({ type: "error", error }); + } + throw e; + } + }; + const request = (...args: Parameters) => + options?.asyncReq ? _reqAsync(...args) : _reqDispatcher(...args); const refresh = () => { const _args = unrefs(requestParams || []) as Parameters; @@ -133,7 +156,7 @@ export function useResource( typeof options?.filter === "function" ? options.filter(..._args) : true; if (_filter) { - return request(..._args); + return _reqDispatcher(..._args); } return undefined; @@ -160,7 +183,7 @@ export function useResource( }, ); - const _rtnState = computed>(() => unref(state)); + const rtnState = computed>(() => unref(state)); - return [_rtnState, request, refresh, cancel]; + return [rtnState, request, refresh, cancel] as UseResourceResult; }