useMemoize
根据参数缓存函数结果并使其保持响应式。它也可以用于异步函数,并将重用现有的 Promise 以避免同时获取相同的数据。
提示
结果不会自动清除。如果您不再需要结果,或者需要使用自己的缓存机制来避免内存泄漏,请调用 clear()
。
用法
ts
import { useMemoize } from '@vueuse/core'
const getUser = useMemoize(
async (userId: number): Promise<UserData> =>
axios.get(`users/${userId}`).then(({ data }) => data),
)
const user1 = await getUser(1) // Request users/1
const user2 = await getUser(2) // Request users/2
// ...
const user1 = await getUser(1) // Retrieve from cache
// ...
const user1 = await getUser.load(1) // Request users/1
// ...
getUser.delete(1) // Delete cache from user 1
getUser.clear() // Clear full cache
js
import { useMemoize } from '@vueuse/core'
const getUser = useMemoize(async (userId) =>
axios.get(`users/${userId}`).then(({ data }) => data),
)
const user1 = await getUser(1) // Request users/1
const user2 = await getUser(2) // Request users/2
// ...
const user1 = await getUser(1) // Retrieve from cache
// ...
const user1 = await getUser.load(1) // Request users/1
// ...
getUser.delete(1) // Delete cache from user 1
getUser.clear() // Clear full cache
与 computed
或 computedAsync
结合使用可实现响应式
ts
const user1 = computedAsync(() => getUser(1))
// ...
await getUser.load(1) // Will also update user1
解析缓存键
缓存的键由提供给函数的参数决定,默认情况下将通过 JSON.stringify
进行序列化。这将允许相等的对象接收相同的缓存键。如果您想自定义键,可以传递 getKey
性能考量
使用 JSON.stringify
作为默认的键生成器对于大型或复杂对象可能会很慢。为了在使用复杂参数时获得更好的性能,强烈建议提供一个自定义的 getKey
函数,该函数根据原始值或唯一标识符生成键。
基本示例
ts
const getUser = useMemoize(
async (userId: number, headers: AxiosRequestHeaders): Promise<UserData> =>
axios.get(`users/${userId}`, { headers }).then(({ data }) => data),
{
// Use only userId to get/set cache and ignore headers
getKey: (userId, headers) => userId,
},
)
js
const getUser = useMemoize(
async (userId, headers) =>
axios.get(`users/${userId}`, { headers }).then(({ data }) => data),
{
// Use only userId to get/set cache and ignore headers
getKey: (userId, headers) => userId,
},
)
自定义缓存机制
默认情况下,结果缓存在 Map
中。您可以通过将 cache
作为选项传入并使用以下结构来实现自己的机制
ts
export interface MemoizeCache<Key, Value> {
/**
* Get value for key
*/
get: (key: Key) => Value | undefined
/**
* Set value for key
*/
set: (key: Key, value: Value) => void
/**
* Return flag if key exists
*/
has: (key: Key) => boolean
/**
* Delete value for key
*/
delete: (key: Key) => void
/**
* Clear cache
*/
clear: () => void
}
js
export {}
类型声明
显示类型声明
ts
type CacheKey = any
/**
* Custom memoize cache handler
*/
export interface UseMemoizeCache<Key, Value> {
/**
* Get value for key
*/
get: (key: Key) => Value | undefined
/**
* Set value for key
*/
set: (key: Key, value: Value) => void
/**
* Return flag if key exists
*/
has: (key: Key) => boolean
/**
* Delete value for key
*/
delete: (key: Key) => void
/**
* Clear cache
*/
clear: () => void
}
/**
* Memoized function
*/
export interface UseMemoizeReturn<Result, Args extends unknown[]> {
/**
* Get result from cache or call memoized function
*/
(...args: Args): Result
/**
* Call memoized function and update cache
*/
load: (...args: Args) => Result
/**
* Delete cache of given arguments
*/
delete: (...args: Args) => void
/**
* Clear cache
*/
clear: () => void
/**
* Generate cache key for given arguments
*/
generateKey: (...args: Args) => CacheKey
/**
* Cache container
*/
cache: UseMemoizeCache<CacheKey, Result>
}
export interface UseMemoizeOptions<Result, Args extends unknown[]> {
getKey?: (...args: Args) => string | number
cache?: UseMemoizeCache<CacheKey, Result>
}
/**
* Reactive function result cache based on arguments
*
* @__NO_SIDE_EFFECTS__
*/
export declare function useMemoize<Result, Args extends unknown[]>(
resolver: (...args: Args) => Result,
options?: UseMemoizeOptions<Result, Args>,
): UseMemoizeReturn<Result, Args>