|
@@ -1,5 +1,4 @@
|
|
|
import type { Ref } from 'vue'
|
|
import type { Ref } from 'vue'
|
|
|
-import type { HttpRequestResult } from '@/http/types'
|
|
|
|
|
import { ref } from 'vue'
|
|
import { ref } from 'vue'
|
|
|
|
|
|
|
|
interface IUseRequestOptions<T> {
|
|
interface IUseRequestOptions<T> {
|
|
@@ -14,7 +13,6 @@ interface IUseRequestReturn<T, P = undefined> {
|
|
|
error: Ref<boolean | Error>
|
|
error: Ref<boolean | Error>
|
|
|
data: Ref<T | undefined>
|
|
data: Ref<T | undefined>
|
|
|
run: (args?: P) => Promise<T | undefined>
|
|
run: (args?: P) => Promise<T | undefined>
|
|
|
- cancel: () => void
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -26,79 +24,31 @@ interface IUseRequestReturn<T, P = undefined> {
|
|
|
* @returns 返回一个对象{loading, error, data, run},包含请求的加载状态、错误信息、响应数据和手动触发请求的函数。
|
|
* @returns 返回一个对象{loading, error, data, run},包含请求的加载状态、错误信息、响应数据和手动触发请求的函数。
|
|
|
*/
|
|
*/
|
|
|
export default function useRequest<T, P = undefined>(
|
|
export default function useRequest<T, P = undefined>(
|
|
|
- func: (args?: P) => Promise<T> | Promise<HttpRequestResult<T>> | HttpRequestResult<T> | T,
|
|
|
|
|
|
|
+ func: (args?: P) => Promise<T>,
|
|
|
options: IUseRequestOptions<T> = { immediate: false },
|
|
options: IUseRequestOptions<T> = { immediate: false },
|
|
|
): IUseRequestReturn<T, P> {
|
|
): IUseRequestReturn<T, P> {
|
|
|
const loading = ref(false)
|
|
const loading = ref(false)
|
|
|
- const error = ref<boolean | Error>(false)
|
|
|
|
|
|
|
+ const error = ref(false)
|
|
|
const data = ref<T | undefined>(options.initialData) as Ref<T | undefined>
|
|
const data = ref<T | undefined>(options.initialData) as Ref<T | undefined>
|
|
|
- let requestTask: UniApp.RequestTask | undefined
|
|
|
|
|
- const isCancelled = ref(false)
|
|
|
|
|
-
|
|
|
|
|
- const run = async (args?: P): Promise<T | undefined> => {
|
|
|
|
|
|
|
+ const run = async (args?: P) => {
|
|
|
loading.value = true
|
|
loading.value = true
|
|
|
- error.value = false
|
|
|
|
|
- isCancelled.value = false
|
|
|
|
|
- let promise: Promise<T | undefined>
|
|
|
|
|
- const result = func(args)
|
|
|
|
|
-
|
|
|
|
|
- if (result instanceof Promise) {
|
|
|
|
|
- promise = result.then((res) => {
|
|
|
|
|
- if (res && typeof (res as HttpRequestResult<T>).promise === 'object' && typeof (res as HttpRequestResult<T>).requestTask === 'object') {
|
|
|
|
|
- const { promise: p, requestTask: task } = res as HttpRequestResult<T>
|
|
|
|
|
- requestTask = task
|
|
|
|
|
- if (isCancelled.value) {
|
|
|
|
|
- task.abort()
|
|
|
|
|
- throw new Error('Request cancelled')
|
|
|
|
|
- }
|
|
|
|
|
- return p
|
|
|
|
|
- }
|
|
|
|
|
- if (isCancelled.value) {
|
|
|
|
|
- throw new Error('Request cancelled')
|
|
|
|
|
- }
|
|
|
|
|
- return res as T | undefined
|
|
|
|
|
- }) as Promise<T | undefined>
|
|
|
|
|
- }
|
|
|
|
|
- else if (result && typeof (result as HttpRequestResult<T>).promise === 'object' && typeof (result as HttpRequestResult<T>).requestTask === 'object') {
|
|
|
|
|
- const { promise: p, requestTask: task } = result as HttpRequestResult<T>
|
|
|
|
|
- requestTask = task
|
|
|
|
|
- promise = p
|
|
|
|
|
- }
|
|
|
|
|
- else {
|
|
|
|
|
- promise = Promise.resolve(result as T | undefined)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return promise
|
|
|
|
|
|
|
+ return func(args)
|
|
|
.then((res) => {
|
|
.then((res) => {
|
|
|
- if (isCancelled.value) {
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
data.value = res
|
|
data.value = res
|
|
|
|
|
+ error.value = false
|
|
|
return data.value
|
|
return data.value
|
|
|
})
|
|
})
|
|
|
.catch((err) => {
|
|
.catch((err) => {
|
|
|
- if (!isCancelled.value) {
|
|
|
|
|
- error.value = err
|
|
|
|
|
- throw err
|
|
|
|
|
- }
|
|
|
|
|
- return Promise.resolve(undefined)
|
|
|
|
|
|
|
+ error.value = err
|
|
|
|
|
+ throw err
|
|
|
})
|
|
})
|
|
|
.finally(() => {
|
|
.finally(() => {
|
|
|
loading.value = false
|
|
loading.value = false
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const cancel = () => {
|
|
|
|
|
- isCancelled.value = true
|
|
|
|
|
- if (requestTask) {
|
|
|
|
|
- requestTask.abort()
|
|
|
|
|
- }
|
|
|
|
|
- loading.value = false
|
|
|
|
|
- error.value = new Error('Request cancelled')
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
if (options.immediate) {
|
|
if (options.immediate) {
|
|
|
- (run as (args?: P) => Promise<T | undefined>)({} as P)
|
|
|
|
|
|
|
+ (run as (args: P) => Promise<T | undefined>)({} as P)
|
|
|
}
|
|
}
|
|
|
- return { loading, error, data, run, cancel }
|
|
|
|
|
|
|
+ return { loading, error, data, run }
|
|
|
}
|
|
}
|