InhiblabCore / vue-hooks-plus

High performance & Simplicity 🧲 Vue 3 Hooks library
https://InhiblabCore.github.io/docs/hooks
MIT License
1.65k stars 104 forks source link

多次执行 run,onSuccess 只会触发一次 #235

Open jianhao opened 6 days ago

jianhao commented 6 days ago

Describe the bug

遇到的问题

我通过useRequest请求数据,loading 初始值为true,多次执行 run 传入不同的参数,获取不同的数据,但是 onSuccess 只会触发一次,打印的是最后一次请求的参数

代码示意图

image

可调试代码链接

问题demo

依赖的资源如下:
"vue": "https://play.vuejs.org/vue.runtime.esm-browser.js",
"vue/server-renderer": "https://play.vuejs.org/server-renderer.esm-browser.js",
"vue-hooks-plus": "https://cdn.jsdelivr.net/npm/vue-hooks-plus/dist/js/index.es.js"

Used Package Manager

npm

Steps to reproduce

多次执行 run,并打印 onSuccess 参数

System Info

- macOS 14
- vue3

Used Package Manager

npm

Validations

SkywalkerJi commented 3 days ago

I have the same problem.

XiaoDaiGua-Ray commented 3 days ago

已经收到问题,正在排查中。

NelsonYong commented 2 days ago

@SkywalkerJi @jianhao 这个行为是预期的,因为 useRequest 内部有实现了请求计数来取消请求和防止无效的请求

问题产生的原因 1、在这一行,请求进来的时候会进行一次计数 https://github.com/InhiblabCore/vue-hooks-plus/blob/7f81dff38eca2052adecee5bac23c46f30b8e7e7/packages/hooks/src/useRequest/Fetch.ts#L118

2、在这一行消费了计数,这里是 runasync 函数里面,且在请求响应后才进行消费, 由于在一个异步函数内,里面消费的 currentCount 是一个快照,而 this.count 则是一个实时的值,因此只会执行一次。 https://github.com/InhiblabCore/vue-hooks-plus/blob/7f81dff38eca2052adecee5bac23c46f30b8e7e7/packages/hooks/src/useRequest/Fetch.ts#L163

我为什么设计呢? 比如上面的例子,假设我同时的对一个接口进行三次保存数据 run(1) run(2) run(3) ,实际上我想到更改的是 3 ,我会认为 1,2 是多余的

cc👆 @XiaoDaiGua-Ray

问题反馈 @SkywalkerJi @jianhao 想问一下你们业务中是有遇到什么场景需要短时间内 run 多次且需要 onSucess 的回调吗?可以将场景描述一下,我将协助你为解决这个问题 🌹

SkywalkerJi commented 2 days ago

@SkywalkerJi @jianhao 这个行为是预期的,因为 useRequest 内部有实现了请求计数来取消请求和防止无效的请求

问题产生的原因 1、在这一行,请求进来的时候会进行一次计数 https://github.com/InhiblabCore/vue-hooks-plus/blob/7f81dff38eca2052adecee5bac23c46f30b8e7e7/packages/hooks/src/useRequest/Fetch.ts#L118

2、在这一行消费了计数,这里是 runasync 函数里面,且在请求响应后才进行消费, 由于在一个异步函数内,里面消费的 currentCount 是一个快照,而 this.count 则是一个实时的值,因此只会执行一次。 https://github.com/InhiblabCore/vue-hooks-plus/blob/7f81dff38eca2052adecee5bac23c46f30b8e7e7/packages/hooks/src/useRequest/Fetch.ts#L163

我为什么设计呢? 比如上面的例子,假设我同时的对一个接口进行三次保存数据 run(1) run(2) run(3) ,实际上我想到更改的是 3 ,我会认为 1,2 是多余的

cc👆 @XiaoDaiGua-Ray

问题反馈 @SkywalkerJi @jianhao 想问一下你们业务中是有遇到什么场景需要短时间内 run 多次且需要 onSucess 的回调吗?可以将场景描述一下,我将协助你为解决这个问题 🌹

可能我没有理解。 我是拿onSucess在获取数据之后格式化返回的内容的。 比如说我给LLM api,同时发送3个请求,分别翻译成中日英。 在返回的onSucess里,我把LLM返回的内容调用另一个检查api,判断是否是目标语种,如果正确就替换一些字符并切割分段。 在现在的情况下,只会有最后一个返回的内容会被检查和格式化。 这个用法是有别的hooks提供吗?

NelsonYong commented 2 days ago

@SkywalkerJi 有的,这种批量处理的是参数不一样的话可以使用 useFetchs, 专门为这种场景而生 https://inhiblabcore.github.io/docs/hooks/useFetchs

可以使用数组循环的 run , 然后再使用 onSucess 去回调,亲测有效,你甚至可以获取到每种请求的状态,比如 loading error 这些 例子

 const arr = ['中文', '日语', '英语', '韩语']

  const { fetchRun, fetchs } = useFetchs(
    getUsername,
    {
      manual: true,
      onSuccess(data, params) {
        console.log('onSuccess', data, params)
      },
    },
    {
      fetchKey: params => {
        return params.desc
      },
    },
  )

  const name = ref()
  name.value = fetchs?.value?.[0]?.data?.desc

  watchEffect(() => {
    arr.forEach(item => {
      fetchRun({ desc: item })
    })
  })
image