57 lines
1.5 KiB
TypeScript
57 lines
1.5 KiB
TypeScript
import { ref, shallowRef, onBeforeUnmount, onDeactivated, onActivated, watch } from 'vue'
|
|
import { useUserStore } from '@/store/modules/user'
|
|
import { gatewayError, requireGatewayAccess } from '@/utils/business/gateway'
|
|
import { pollingScope } from '@/utils/business/pollingScheduler'
|
|
|
|
export function useSchedulerRequest<T>(request: () => Promise<T>, allowed: () => boolean) {
|
|
const user = useUserStore()
|
|
const data = shallowRef<T | null>(null),
|
|
loading = ref(false),
|
|
error = ref('')
|
|
let sequence = 0,
|
|
active = true
|
|
function clear() {
|
|
++sequence
|
|
data.value = null
|
|
loading.value = false
|
|
error.value = ''
|
|
}
|
|
async function load() {
|
|
if (!active) return
|
|
const current = ++sequence,
|
|
scope = pollingScope(user)
|
|
loading.value = true
|
|
error.value = ''
|
|
data.value = null
|
|
try {
|
|
requireGatewayAccess(allowed())
|
|
const result = await request()
|
|
if (active && current === sequence && scope === pollingScope(user) && allowed())
|
|
data.value = result
|
|
} catch (cause) {
|
|
if (active && current === sequence) {
|
|
data.value = null
|
|
error.value = gatewayError(cause)
|
|
}
|
|
} finally {
|
|
if (current === sequence) loading.value = false
|
|
}
|
|
}
|
|
watch(() => [pollingScope(user), allowed()], clear, { flush: 'sync' })
|
|
onDeactivated(() => {
|
|
active = false
|
|
clear()
|
|
})
|
|
onActivated(() => {
|
|
if (!active) {
|
|
active = true
|
|
void load()
|
|
}
|
|
})
|
|
onBeforeUnmount(() => {
|
|
active = false
|
|
clear()
|
|
})
|
|
return { data, loading, error, load }
|
|
}
|