vueuse
vueuse copied to clipboard
useAsyncFunction
Clear and concise description of the problem
I would love a hook, that makes getting the pending state of an async function easier.
Currently I find myself writing this kind of boilerplate a lot:
import { logout } from '@/store/auth'
const logoutPending = ref(false)
async function handleLogout() {
logoutPending.value = true
await logout()
logoutPending.value = false
}
Therefore I created a use hook for that and would like to submit a PR to implement this hook for VueUse. It can be used as follows:
import { logout } from '@/store/auth'
import { useAsyncFunction } from '@/utils'
const { pending: logoutPending, trigger: handleLogout } = useAsyncFunction(logout)
Suggested solution
Simple Implementation
In the core module, we could provide this implementation:
import { Ref } from 'vue'
export function useAsyncFunction<TArgs extends any[], TReturn extends any>(
fn: (...args: TArgs) => Promise<TReturn>
): {
pending: Ref<boolean>
trigger: (...args: TArgs) => Promise<TReturn | undefined>
} {
const pending = ref(false)
async function trigger(...args: TArgs) {
if (pending.value) {
return
}
pending.value = true
const result = await fn(...args)
pending.value = false
return result
}
return {
pending,
trigger,
}
}
Possible features to enhance this hook
-
stateordataref that contains the latest result -
abortmethod to cancel the running async call(s) - allow
triggerto be called multiple times and handlependingfor multiple calls - add
abortPendingOnTriggeroption to automatically abort pending calls when triggering a new one - add
pendingCountoption to see how many calls are currently pending - add
accumulateResultsoption to makestatebe an array of results that were returned
Alternative
Just figured out, that useAsyncState can achieve something similar:
const { execute, isLoading } = useAsyncState(() => logout(), null, {
immediate: false,
})
It might be enough to add some examples to the docs of useAsyncState that show these use cases. However we could still provide a thin wrapper around useAsyncState that makes the usage more intuitive for the use case explained above.
Additional context
No response
Validations
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guidelines.
- [X] Read the docs.
- [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.