useRequest custom cache support async getCache
Description
能否支持异步调用的 getCache
Suggested solution
useCachePlugin.js 中的 方法 getCache 使用 async await 调用
Alternative
No response
Additional context
No response
Validations
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guidelines.
- [X] Read the docs.
- [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
能否给一个示例,否则不知道你的使用场景和需求是什么
能否给一个示例,否则不知道你的使用场景和需求是什么
因为想使用 localforage 进行数据缓存,而 localforage 的 getItem 是一个异步行为
或许你可以自己使用 Promise 包裹一层,这边暂时不考虑异步行为。
或许你可以自己使用 Promise 包裹一层,这边暂时不考虑异步行为。
但是文档中提及可以使用 IndexDB,IndexDB 本身也是异步的
如果在 geCache 中进行 Promise 返回,那返回的值被转为 ref 时会直接变成 undefined,缓存就失效了
如果 getCache 中是同步行为,就不存在缓存失效的问题
你的写法有点不对,明天我尝试还原你的使用场景给你一个答复。感谢你的支持~
@BreathlessWay 后续会考虑支持
目前 getCache 确实不支持异步的。
@BreathlessWay 我们将在 2.x 探索如何进行优雅的异步获取缓存
@BreathlessWay 经过一段时间的调研,得出一个结论:如果在内部进行异步缓存的改造,对整个 useRequest 的功能会造成比较大的破坏性。
如果针对异步的缓存,如何在现有的基础上以最小成本实现呢?
我针对现有的功能实现了一个方案,自定义程度比较高,应该可以满足你现有的需求。它的缺点也很明显,会让你的心智负担增加。
在这个例子中,将异步获取缓存的操作当成是一个请求,缓存相当于初始值,因此当目前请求没到来之前使用缓存值,即 data ?? cacheData
<template>
<div>
<vhp-button @click="() => toggle()">show/hidden</vhp-button>
<div v-if="state" style="padding: 16px;">
<p>{{ data ?? cacheData }}</p>
<div> cacheData: {{ cacheData }} </div>
</div>
</div>
</template>
<script lang="ts" setup>
import { useRequest, useToggle } from 'vue-hooks-plus'
const cacheKey = 'cacheKey-async-storage'
const asyncStorage = {
setItem: (key: string, value: any) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
localStorage.setItem(key, value)
resolve(value)
}, 200)
})
},
getItem: (key: string) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(localStorage.getItem(key))
}, 100)
})
},
}
const [state, { toggle }] = useToggle()
const { data: cacheData, refresh } = useRequest(
() => asyncStorage.getItem(cacheKey) as Promise<string>,
{
cacheKey,
debugKey: cacheKey,
},
)
function getUsername(refresh: VoidFunction): Promise<string> {
return new Promise(resolve => {
setTimeout(() => {
asyncStorage.setItem(cacheKey, String(Date.now())).then(() => {
refresh()
})
resolve(String(Date.now()))
}, 1000)
})
}
const { data } = useRequest(() => getUsername(refresh), {
ready: state,
cacheKey: 'cacheKey-get-username',
})
</script>