vue-hooks-plus icon indicating copy to clipboard operation
vue-hooks-plus copied to clipboard

useRequest custom cache support async getCache

Open BreathlessWay opened this issue 1 year ago • 8 comments

Description

能否支持异步调用的 getCache

Suggested solution

useCachePlugin.js 中的 方法 getCache 使用 async await 调用

Alternative

No response

Additional context

No response

Validations

BreathlessWay avatar Jan 29 '24 09:01 BreathlessWay

能否给一个示例,否则不知道你的使用场景和需求是什么

XiaoDaiGua-Ray avatar Feb 04 '24 08:02 XiaoDaiGua-Ray

能否给一个示例,否则不知道你的使用场景和需求是什么

因为想使用 localforage 进行数据缓存,而 localforage 的 getItem 是一个异步行为

BreathlessWay avatar Feb 19 '24 05:02 BreathlessWay

或许你可以自己使用 Promise 包裹一层,这边暂时不考虑异步行为。

XiaoDaiGua-Ray avatar Feb 20 '24 02:02 XiaoDaiGua-Ray

或许你可以自己使用 Promise 包裹一层,这边暂时不考虑异步行为。

但是文档中提及可以使用 IndexDB,IndexDB 本身也是异步的

image

如果在 geCache 中进行 Promise 返回,那返回的值被转为 ref 时会直接变成 undefined,缓存就失效了

image

image

如果 getCache 中是同步行为,就不存在缓存失效的问题 image

image

BreathlessWay avatar Feb 20 '24 08:02 BreathlessWay

你的写法有点不对,明天我尝试还原你的使用场景给你一个答复。感谢你的支持~

XiaoDaiGua-Ray avatar Feb 20 '24 12:02 XiaoDaiGua-Ray

@BreathlessWay 后续会考虑支持

NelsonYong avatar Feb 26 '24 03:02 NelsonYong

目前 getCache 确实不支持异步的。

NelsonYong avatar Feb 26 '24 03:02 NelsonYong

@BreathlessWay 我们将在 2.x 探索如何进行优雅的异步获取缓存

NelsonYong avatar May 15 '24 02:05 NelsonYong

@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>

NelsonYong avatar Oct 08 '24 08:10 NelsonYong