Skip to content

useMemoize

类别
导出体积
242 B
上次更改
2 months ago

缓存依赖于参数的函数结果,并保持其响应性。它还可以用于异步函数,并将重用现有的 promises 来避免同时获取相同的数据。

TIP

结果不会自动清除。如果你不再需要结果,请调用 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) // 请求 users/1
const
user2
= await
getUser
(2) // 请求 users/2
// ... const
user1
= await
getUser
(1) // 从缓存中获取
// ... const
user1
= await
getUser
.
load
(1) // 请求 users/1
// ...
getUser
.
delete
(1) // 删除用户1的缓存
getUser
.
clear
() // 清除完整缓存
js
import { useMemoize } from '@vueuse/core'
const getUser = useMemoize(async (userId) =>
  axios.get(`users/${userId}`).then(({ data }) => data),
)
const user1 = await getUser(1) // 请求 users/1
const user2 = await getUser(2) // 请求 users/2
// ...
const user1 = await getUser(1) // 从缓存中获取
// ...
const user1 = await getUser.load(1) // 请求 users/1
// ...
getUser.delete(1) // 删除用户1的缓存
getUser.clear() // 清除完整缓存

结合 computedcomputedAsync 可以实现响应性:

ts
const 
user1
=
computedAsync
(() =>
getUser
(1))
// ... await
getUser
.
load
(1) // 也会更新 user1

解析缓存键

缓存的键由传递给函数的参数确定,并且默认情况下将使用 JSON.stringify 进行序列化。 这将使相等的对象接收相同的缓存键。如果你想自定义键,可以通过 getKey 传递。

ts
const 
getUser
=
useMemoize
(
async (
userId
: number,
headers
:
AxiosRequestHeaders
):
Promise
<
UserData
> =>
axios.get(`users/${
userId
}`, {
headers
}).then(({
data
}) =>
data
),
{ // 仅使用 userId 获取/设置缓存,忽略 headers
getKey
: (
userId
,
headers
) =>
userId
,
}, )
js
const getUser = useMemoize(
  async (userId, headers) =>
    axios.get(`users/${userId}`, { headers }).then(({ data }) => data),
  {
    // 仅使用 userId 获取/设置缓存,忽略 headers
    getKey: (userId, headers) => userId,
  },
)

自定义缓存机制

默认情况下,结果会缓存到一个 Map 中。您可以通过传递 cache 作为选项,使用以下结构来实现您自己的机制:

ts
export interface 
MemoizeCache
<
Key
,
Value
> {
/** * 获取键的值 */
get
: (
key
:
Key
) =>
Value
| undefined
/** * 为键设置值 */
set
: (
key
:
Key
,
value
:
Value
) => void
/** * 返回键是否存在的标志 */
has
: (
key
:
Key
) => boolean
/** * 删除键的值 */
delete
: (
key
:
Key
) => void
/** * 清除缓存 */
clear
: () => void
}
js
export {}

类型声明

显示类型声明
ts
type 
CacheKey
= any
/** * 自定义记忆缓存处理程序 */ export interface
UseMemoizeCache
<
Key
,
Value
> {
/** * 获取键的值 */
get
: (
key
:
Key
) =>
Value
| undefined
/** * 设置键的值 */
set
: (
key
:
Key
,
value
:
Value
) => void
/** * 返回键是否存在的标志 */
has
: (
key
:
Key
) => boolean
/** * 删除键的值 */
delete
: (
key
:
Key
) => void
/** * 清除缓存 */
clear
: () => void
} /** * 记忆化函数 */ export interface
UseMemoizeReturn
<
Result
,
Args
extends unknown[]> {
/** * 从缓存中获取结果或调用记忆化函数 */ (...
args
:
Args
):
Result
/** * 调用记忆化函数并更新缓存 */
load
: (...
args
:
Args
) =>
Result
/** * 删除给定参数的缓存 */
delete
: (...
args
:
Args
) => void
/** * 清除缓存 */
clear
: () => void
/** * 为给定参数生成缓存键 */
generateKey
: (...
args
:
Args
) =>
CacheKey
/** * 缓存容器 */
cache
:
UseMemoizeCache
<
CacheKey
,
Result
>
} export interface
UseMemoizeOptions
<
Result
,
Args
extends unknown[]> {
getKey
?: (...
args
:
Args
) => string | number
cache
?:
UseMemoizeCache
<
CacheKey
,
Result
>
} /** * 基于参数的响应式函数结果缓存 * * @__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
Vida Xie
Mikhailov Nikita
Jelf
freakzlike

更新日志

d32f8 - refactor: add @__NO_SIDE_EFFECTS__ annotations to all pure functions (#4907)
0a9ed - feat!: drop Vue 2 support, optimize bundles and clean up (#4349)
a086e - fix: stricter types
fecbe - fix: use shallowReactive to wrap Map