Skip to content
On this page

until

Category
Export Size
653 B
Last Changed
3 months ago

Promised one-time watch for changes

Demo

Add to 7 to show the alert.

Count: 0

Usage

Wait for some async data to be ready

js
import { until, useAsyncState } from '@vueuse/core'

const { state, isReady } = useAsyncState(
  fetch('https://jsonplaceholder.typicode.com/todos/1').then(t => t.json()),
  {},
)

;(async () => {
  await until(isReady).toBe(true)

  console.log(state) // state is now ready!
})()
import { until, useAsyncState } from '@vueuse/core'

const { state, isReady } = useAsyncState(
  fetch('https://jsonplaceholder.typicode.com/todos/1').then(t => t.json()),
  {},
)

;(async () => {
  await until(isReady).toBe(true)

  console.log(state) // state is now ready!
})()

Wait for custom conditions

You can use invoke to call the async function.

js
import { invoke, until, useCounter } from '@vueuse/core'

const { count } = useCounter()

invoke(async () => {
  await until(count).toMatch(v => v > 7)

  alert('Counter is now larger than 7!')
})
import { invoke, until, useCounter } from '@vueuse/core'

const { count } = useCounter()

invoke(async () => {
  await until(count).toMatch(v => v > 7)

  alert('Counter is now larger than 7!')
})

Timeout

ts
// will be resolve until ref.value === true or 1000ms passed
await until(ref).toBe(true, { timeout: 1000 })

// will throw if timeout
try {
  await until(ref).toBe(true, { timeout: 1000, throwOnTimeout: true })
  // ref.value === true
}
catch (e) {
  // timeout
}
// will be resolve until ref.value === true or 1000ms passed
await until(ref).toBe(true, { timeout: 1000 })

// will throw if timeout
try {
  await until(ref).toBe(true, { timeout: 1000, throwOnTimeout: true })
  // ref.value === true
}
catch (e) {
  // timeout
}

More Examples

ts
await until(ref).toBe(true)
await until(ref).toMatch(v => v > 10 && v < 100)
await until(ref).changed()
await until(ref).changedTimes(10)
await until(ref).toBeTruthy()
await until(ref).toBeNull()

await until(ref).not.toBeNull()
await until(ref).not.toBeTruthy()
await until(ref).toBe(true)
await until(ref).toMatch(v => v > 10 && v < 100)
await until(ref).changed()
await until(ref).changedTimes(10)
await until(ref).toBeTruthy()
await until(ref).toBeNull()

await until(ref).not.toBeNull()
await until(ref).not.toBeTruthy()

Type Declarations

Show Type Declarations
typescript
export interface UntilToMatchOptions {
  /**
   * Milliseconds timeout for promise to resolve/reject if the when condition does not meet.
   * 0 for never timed out
   *
   * @default 0
   */
  timeout?: number
  /**
   * Reject the promise when timeout
   *
   * @default false
   */
  throwOnTimeout?: boolean
  /**
   * `flush` option for internal watch
   *
   * @default 'sync'
   */
  flush?: WatchOptions["flush"]
  /**
   * `deep` option for internal watch
   *
   * @default 'false'
   */
  deep?: WatchOptions["deep"]
}
export interface UntilBaseInstance<T, Not extends boolean = false> {
  toMatch<U extends T = T>(
    condition: (v: T) => v is U,
    options?: UntilToMatchOptions
  ): Not extends true ? Promise<Exclude<T, U>> : Promise<U>
  toMatch(
    condition: (v: T) => boolean,
    options?: UntilToMatchOptions
  ): Promise<T>
  changed(options?: UntilToMatchOptions): Promise<T>
  changedTimes(n?: number, options?: UntilToMatchOptions): Promise<T>
}
declare type Falsy = false | void | null | undefined | 0 | 0n | ""
export interface UntilValueInstance<T, Not extends boolean = false>
  extends UntilBaseInstance<T, Not> {
  readonly not: UntilValueInstance<T, Not extends true ? false : true>
  toBe<P = T>(
    value: MaybeComputedRef<P>,
    options?: UntilToMatchOptions
  ): Not extends true ? Promise<T> : Promise<P>
  toBeTruthy(
    options?: UntilToMatchOptions
  ): Not extends true ? Promise<T & Falsy> : Promise<Exclude<T, Falsy>>
  toBeNull(
    options?: UntilToMatchOptions
  ): Not extends true ? Promise<Exclude<T, null>> : Promise<null>
  toBeUndefined(
    options?: UntilToMatchOptions
  ): Not extends true ? Promise<Exclude<T, undefined>> : Promise<undefined>
  toBeNaN(options?: UntilToMatchOptions): Promise<T>
}
export interface UntilArrayInstance<T> extends UntilBaseInstance<T> {
  readonly not: UntilArrayInstance<T>
  toContains(
    value: MaybeComputedRef<ElementOf<ShallowUnwrapRef<T>>>,
    options?: UntilToMatchOptions
  ): Promise<T>
}
/**
 * Promised one-time watch for changes
 *
 * @see https://vueuse.org/until
 * @example
 * ```
 * const { count } = useCounter()
 *
 * await until(count).toMatch(v => v > 7)
 *
 * alert('Counter is now larger than 7!')
 * ```
 */
export declare function until<T extends unknown[]>(
  r: WatchSource<T> | MaybeComputedRef<T>
): UntilArrayInstance<T>
export declare function until<T>(
  r: WatchSource<T> | MaybeComputedRef<T>
): UntilValueInstance<T>
export interface UntilToMatchOptions {
  /**
   * Milliseconds timeout for promise to resolve/reject if the when condition does not meet.
   * 0 for never timed out
   *
   * @default 0
   */
  timeout?: number
  /**
   * Reject the promise when timeout
   *
   * @default false
   */
  throwOnTimeout?: boolean
  /**
   * `flush` option for internal watch
   *
   * @default 'sync'
   */
  flush?: WatchOptions["flush"]
  /**
   * `deep` option for internal watch
   *
   * @default 'false'
   */
  deep?: WatchOptions["deep"]
}
export interface UntilBaseInstance<T, Not extends boolean = false> {
  toMatch<U extends T = T>(
    condition: (v: T) => v is U,
    options?: UntilToMatchOptions
  ): Not extends true ? Promise<Exclude<T, U>> : Promise<U>
  toMatch(
    condition: (v: T) => boolean,
    options?: UntilToMatchOptions
  ): Promise<T>
  changed(options?: UntilToMatchOptions): Promise<T>
  changedTimes(n?: number, options?: UntilToMatchOptions): Promise<T>
}
declare type Falsy = false | void | null | undefined | 0 | 0n | ""
export interface UntilValueInstance<T, Not extends boolean = false>
  extends UntilBaseInstance<T, Not> {
  readonly not: UntilValueInstance<T, Not extends true ? false : true>
  toBe<P = T>(
    value: MaybeComputedRef<P>,
    options?: UntilToMatchOptions
  ): Not extends true ? Promise<T> : Promise<P>
  toBeTruthy(
    options?: UntilToMatchOptions
  ): Not extends true ? Promise<T & Falsy> : Promise<Exclude<T, Falsy>>
  toBeNull(
    options?: UntilToMatchOptions
  ): Not extends true ? Promise<Exclude<T, null>> : Promise<null>
  toBeUndefined(
    options?: UntilToMatchOptions
  ): Not extends true ? Promise<Exclude<T, undefined>> : Promise<undefined>
  toBeNaN(options?: UntilToMatchOptions): Promise<T>
}
export interface UntilArrayInstance<T> extends UntilBaseInstance<T> {
  readonly not: UntilArrayInstance<T>
  toContains(
    value: MaybeComputedRef<ElementOf<ShallowUnwrapRef<T>>>,
    options?: UntilToMatchOptions
  ): Promise<T>
}
/**
 * Promised one-time watch for changes
 *
 * @see https://vueuse.org/until
 * @example
 * ```
 * const { count } = useCounter()
 *
 * await until(count).toMatch(v => v > 7)
 *
 * alert('Counter is now larger than 7!')
 * ```
 */
export declare function until<T extends unknown[]>(
  r: WatchSource<T> | MaybeComputedRef<T>
): UntilArrayInstance<T>
export declare function until<T>(
  r: WatchSource<T> | MaybeComputedRef<T>
): UntilValueInstance<T>

Source

SourceDemoDocs

Contributors

Anthony Fu
sun0day
lsdsjy
Mitchell
Jeff Zou
wheat
Shinigami
Alex Kozack

Changelog

v9.3.0 on 9/26/2022
1f656 - fix: .not returns new instance (#2224)
v8.9.1 on 7/8/2022
a9ccc - feat(all): use MaybeComputedRef (#1768)
v8.7.0 on 6/16/2022
c4853 - feat: improved until types (#1493)

Released under the MIT License.