diff --git a/packages/core/useAsyncState/index.test.ts b/packages/core/useAsyncState/index.test.ts index cae4e009d14..bf329dd4da0 100644 --- a/packages/core/useAsyncState/index.test.ts +++ b/packages/core/useAsyncState/index.test.ts @@ -27,6 +27,13 @@ describe('useAsyncState', () => { expect(state.value).toBe(2) }) + it('should work with await', async () => { + const asyncState = useAsyncState(p1, 0, { immediate: true }) + expect(asyncState.isLoading.value).toBeTruthy() + await asyncState + expect(asyncState.isLoading.value).toBeFalsy() + }) + it('should work with isLoading', () => { const { execute, isLoading } = useAsyncState(p1, 0, { immediate: false }) expect(isLoading.value).toBeFalsy() diff --git a/packages/core/useAsyncState/index.ts b/packages/core/useAsyncState/index.ts index 726d471eba4..627e2970ab5 100644 --- a/packages/core/useAsyncState/index.ts +++ b/packages/core/useAsyncState/index.ts @@ -1,8 +1,8 @@ -import { noop, promiseTimeout } from '@vueuse/shared' +import { noop, promiseTimeout, until } from '@vueuse/shared' import type { Ref, UnwrapRef } from 'vue-demi' import { ref, shallowRef } from 'vue-demi' -export interface UseAsyncStateReturn { +export interface UseAsyncStateReturnBase { state: Shallow extends true ? Ref : Ref> isReady: Ref isLoading: Ref @@ -10,6 +10,10 @@ export interface UseAsyncStateReturn Promise } +export type UseAsyncStateReturn = + UseAsyncStateReturnBase + & PromiseLike> + export interface UseAsyncStateOptions { /** * Delay for executing the promise. In milliseconds. @@ -129,11 +133,27 @@ export function useAsyncState = { state: state as Shallow extends true ? Ref : Ref>, isReady, isLoading, error, execute, } + + function waitUntilIsLoaded() { + return new Promise>((resolve, reject) => { + until(isLoading).toBe(false) + .then(() => resolve(shell)) + .catch(reject) + }) + } + + return { + ...shell, + then(onFulfilled, onRejected) { + return waitUntilIsLoaded() + .then(onFulfilled, onRejected) + }, + } }