跳到主要内容

useMemoize

分类
导出大小
242 B
上次更改
3 个月前

根据参数缓存函数结果并使其保持响应式。它也可以用于异步函数,并将重用现有的 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

computedcomputedAsync 结合使用可实现响应式

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
>

来源

源代码文档

贡献者

Anthony Fu
SerKo
Anthony Fu
broBinChen
Vida Xie
Mikhailov Nikita
Jelf
freakzlike

更新日志

v13.6.0
d32f8 - refactor: 为所有纯函数添加 @__NO_SIDE_EFFECTS__ 注释 (#4907)
0a9ed - feat!: 放弃对 Vue 2 的支持,优化打包并清理 (#4349)
v10.8.0
a086e - fix: 更严格的类型
v10.7.0
fecbe - fix: 使用 shallowReactive 包装 Map

根据 MIT 许可证发布。