rxjs 节流获取直到请求完成 [英] rxjs throttle fetch until request has finished

查看:63
本文介绍了rxjs 节流获取直到请求完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Observable,它发出一个请求,每次返回一些不同的信息.这个 observable 由用户点击按钮调用.我想阻止用户在请求返回信息之前点击这个按钮,一旦它返回,允许用户再次点击更新.

I have an Observable that makes a request that gives back some information that is different each time. This observable is called by a user clicking a button. I want to prevent the user from clicking this button before the request has returned with information, and once it has returned, allow the user to click for an update once again.

这是在任何时候都不会停止用户的请求.

This is the request without stopping the user at any point.

const fetchRepos = () =>
  fetch( 'https://api.github.com/search/repositories?q=+language:javascript&sort=updated&order=desc')
    .then(response => response.json())

export function fetchReposEpic(action$: any) {
  return action$.ofType(FETCH_POPULAR_REPOS_REQUEST)
    .switchMap(fetchRepos)
    .map(data => ({
      type: FETCH_POPULAR_REPOS_SUCCESS,
      payload: data.items
    }))
}

一种解决方案是在 Observable 开始后限制用户 500 毫秒

One solution is to throttle the user for 500 milliseconds after the Observable begins

export function fetchReposEpic(action$: any) {
  return action$.ofType(FETCH_POPULAR_REPOS_REQUEST)
    .throttleTime(500)
    .switchMap(fetchRepos)
    .map(data => ({
      type: FETCH_POPULAR_REPOS_SUCCESS,
      payload: data.items
    }))
}

这里的问题是我只是估计请求可能需要多长时间,更糟糕的是,如果请求在此时间之前完成,用户可以点击按钮,点击将被忽略.

The problem here is I am only estimating how long the request might take, worse still, if the request finishes before this time, the user could click the button and the click would be ignored.

最接近我的解决方案是将 fetch 承诺传递给限制.

The closest to a solution I have is passing the fetch promise to throttle.

export function fetchReposEpic(action$: any) {
  return action$.ofType(FETCH_POPULAR_REPOS_REQUEST)
    .throttle(fetchRepos)
    .map(data => ({
      type: FETCH_POPULAR_REPOS_SUCCESS,
      payload: []
    }))
}

这将等到请求完成并在此之前限制所有其他操作.问题是我不知道如何获得油门的返回值.我能找到的所有 油门示例也显示了被丢弃的油门的返回值.

This will wait until the request has finished and will throttle all other actions until then. The problem is that I do not know how to get the returned value of throttle. All throttle examples I could find also show the returned value of throttle being thrown away.

总而言之,我想要一种方法,可以等到 observable 完成后再再次触发它.

So to summarize, I want a way to wait until the observable has completed before firing it off again.

推荐答案

解决方案是让您的 UI 基于 redux 中的某些状态禁用按钮,例如 isFetchingRepos 并且您的 reducer 会将其翻转为true 接收到 FETCH_POPULAR_REPOS_REQUESTfalse 接收 FETCH_POPULAR_REPOS_SUCCESS 时.

The solution is for your UI to disable the button based on some state in redux, like isFetchingRepos and your reducers will flip this to true when FETCH_POPULAR_REPOS_REQUEST is received and false when FETCH_POPULAR_REPOS_SUCCESS is.

如果您稍后添加错误处理,请确保在看到错误操作时也将其翻转回 false.

If you later add error handling, make sure you also flip it back to false when an error action is seen.

文档中的 ping/pong 示例实际上大致相同 https://redux-observable.js.org/docs/basics/Epics.html#a-basic-example.如何在商店中构建/存储该状态取决于您 - 对于涉及 ID 且可能发生并发请求的更复杂情况,您需要确保状态是每个请求(或 ID,如果使用 switchMap)

The ping/pong example in the docs is actually mostly the same thing https://redux-observable.js.org/docs/basics/Epics.html#a-basic-example. How you structure/store that state in your store is up to you--for more complex cases where ID's are involved and concurrent requests can happen, you'll want to make sure that state is per request (or ID if using switchMap)

这篇关于rxjs 节流获取直到请求完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆