computedAsync
计算异步函数。
用法
import { computedAsync } from '@vueuse/core'
import { shallowRef } from 'vue'
const name = shallowRef('jack')
const userInfo = computedAsync(
async () => {
return await mockLookUp(name.value)
},
null, // 初始状态
)
计算状态
你需要传入一个 ref 来跟踪异步函数是否正在评估。
import { computedAsync } from '@vueuse/core'
import { shallowRef } from 'vue'
const evaluating = shallowRef(false)
const userInfo = computedAsync(
async () => { /* 你的逻辑 */ },
null,
evaluating,
)
onCancel
当 computed 源在之前的异步函数解析完成之前发生变化时,你可能需要取消之前的异步函数。这里有一个示例展示了如何结合 fetch API 使用。
const packageName = shallowRef('@vueuse/core')
const downloads = computedAsync(async (onCancel) => {
const abortController = new AbortController()
onCancel(() => abortController.abort())
return await fetch(
`https://api.npmjs.org/downloads/point/last-week/${packageName.value}`,
{ signal: abortController.signal },
)
.then(response => response.ok ? response.json() : { downloads: '—' })
.then(result => result.downloads)
}, 0)
惰性
默认情况下,computedAsync 会在创建时立即开始解析,指定 lazy: true 会使其在第一次访问时才开始解析。
import { computedAsync } from '@vueuse/core'
import { shallowRef } from 'vue'
const evaluating = shallowRef(false)
const userInfo = computedAsync(
async () => { /* 你的逻辑 */ },
null,
{ lazy: true, evaluating },
)
注意事项
- 就像 Vue 内置的
computed函数一样,computedAsync会进行依赖跟踪并在依赖变化时自动重新评估。但请注意,只有在第一个调用堆栈中引用的依赖才会被考虑在内。换句话说:异步访问的依赖不会触发异步计算值的重新评估。 - 与 Vue 内置的
computed函数不同,异步计算值的重新评估会在依赖变化时触发,无论其结果当前是否被跟踪。
类型声明
/**
* Handle overlapping async evaluations.
*
* @param cancelCallback The provided callback is invoked when a re-evaluation of the computed value is triggered before the previous one finished
*/
export type AsyncComputedOnCancel = (cancelCallback: Fn) => void
export interface AsyncComputedOptions<Lazy = boolean> {
/**
* Should value be evaluated lazily
*
* @default false
*/
lazy?: Lazy
/**
* Ref passed to receive the updated of async evaluation
*/
evaluating?: Ref<boolean>
/**
* Use shallowRef
*
* @default true
*/
shallow?: boolean
/**
* The flush option allows for greater control over the timing of a history point, default to `pre`
*
* Possible values: `pre`, `post`, `sync`
*
* It works in the same way as the flush option in watch and watch effect in vue reactivity
* @default 'pre'
*/
flush?: "pre" | "post" | "sync"
/**
* Callback when error is caught.
*/
onError?: (e: unknown) => void
}
/**
* Create an asynchronous computed dependency.
*
* @see https://vueuse.org/computedAsync
* @param evaluationCallback The promise-returning callback which generates the computed value
* @param initialState The initial state, used until the first evaluation finishes
* @param optionsOrRef Additional options or a ref passed to receive the updates of the async evaluation
*/
export declare function computedAsync<T>(
evaluationCallback: (onCancel: AsyncComputedOnCancel) => T | Promise<T>,
initialState: T,
optionsOrRef: AsyncComputedOptions<true>,
): ComputedRef<T>
export declare function computedAsync<T>(
evaluationCallback: (onCancel: AsyncComputedOnCancel) => T | Promise<T>,
initialState: undefined,
optionsOrRef: AsyncComputedOptions<true>,
): ComputedRef<T | undefined>
export declare function computedAsync<T>(
evaluationCallback: (onCancel: AsyncComputedOnCancel) => T | Promise<T>,
initialState: T,
optionsOrRef?: Ref<boolean> | AsyncComputedOptions,
): Ref<T>
export declare function computedAsync<T>(
evaluationCallback: (onCancel: AsyncComputedOnCancel) => T | Promise<T>,
initialState?: undefined,
optionsOrRef?: Ref<boolean> | AsyncComputedOptions,
): Ref<T | undefined>
export { computedAsync as asyncComputed }