rxjs 节流获取直到请求完成

rxjs throttle fetch until request has finished

我有一个 Observable 发出请求,每次返回一些不同的信息。该可观察对象由用户单击按钮调用。我想阻止用户在请求返回信息之前单击此按钮,并且在返回后允许用户再次单击以获取更新。

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

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 毫秒

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
    }))
}

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

最接近我的解决方案是将获取承诺传递给 throttle。

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

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

总而言之,我想要一种方法来等待 observable 完成后再将其再次触发。

解决方案是 UI 根据 redux 中的某些状态禁用按钮,例如 isFetchingRepos,当 FETCH_POPULAR_REPOS_REQUEST 时,reducer 会将其翻转为 true收到 falseFETCH_POPULAR_REPOS_SUCCESS 收到。

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

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