Redux-Observable - 如果下一个请求与当前请求具有相同的参数,则取消下一个请求,但当它们不同时让它 运行

Redux-Observable - Cancel next request if it has same parameters with current one, but let it run when they are different

我是响应式编程的新手。只是想了解可观察对象和 rxjs 运算符。我有一个 react-redux 应用程序,它有一个自定义中间件来处理缓存数据和 isFetching 标志。虽然它只处理我需要的事情,但对于取消或去抖动之类的事情可能会很复杂。所以,我想将此应用程序迁移到 redux-observable.

如果当前正在提取同一部电影,我不想提取它。我只是将 selectIsFetchingMovieById(action.movieId) 选择器传递给自定义中间件。如果它 returns true,它不会将任何东西传递给 reducer。 But when the selector returns false, it fetches the movie, 运行s through either .then or .catch like any regular promise based fetch data process.

但是当我使用 redux-observable 时,给定 movieId 的 isFetching 状态已经是 true。因为 reducer 已经得到了 ({type: FETCH_MOVIE_REQUEST, movieId: "10" }) 动作。选择器总是 returns true.

如果我使用switchMap,它会取消之前的请求,即使它有不同的movieId。 exhaustMap 不会 运行 下一个请求,即使它有不同的 movieId 等

现在我有了这部史诗。它适用于 cachedData 情况。如果商店已经有电影,则不会继续。但是isFetching基于movieId还是有问题

const fetchMovieEpic = (action$, state$) =>
  action$.pipe(
    ofType(actionTypes.FETCH_MOVIE_REQUEST),
    filter(action => {
      const cachedData = selectors.selectMovie(state$.value, action.movieId);
      return !verifyCachedData(cachedData, action.requiredFields);
    }),
    map(action => action.movieId),
    switchMap(movieId =>
      ajax.getJSON(`${BASE_API_URL}/movie/${movieId}?api_key=${api_key}`).pipe(
        map(response => normalize(response, schemas.movieSchema)),
        map(normalizedData => fetchMovieSuccess(movieId, normalizedData)),
        catchError(() => of(fetchMovieError())),
        takeUntil(
          action$.pipe(
            ofType("FETCH_MOVIE_CANCELLED"),
            filter(action => action.movieId === movieId)
          )
        )
      )
    )
  );

我如何使用 rxjs 运算符或任何其他技术来实现它?我不想添加像 FETCH_MOVIE_TOGGLE_LOADING 这样的额外 actionType。我已经有 REQUESTSUCCESSERRORCANCELLED。还有很多其他的减速器和 epics。因此,使用运算符保持简单可能是一个不错的选择:)

谢谢!

根据定义 exhaustMap 假设可以工作。您可以通过重组流并简化内部流来调试它

exhaustMap(movieId =>ajax.getJSON(`${BASE_API_URL}/movie/${movieId}?api_key=${api_key}`).pipe(catchError(() => of(fetchMovieError()))
),

并查看后续操作是否会在请求完成后触发

我知道有点晚了,我实际上已经放弃使用 redux-observable。我无法用它编写我想要的代码。这让我觉得它不容易阅读。

坚持使用 redux-thunk 并在特殊情况下使用 redux-saga 可能要容易得多。至少对我来说是。

这是我在分组解决方案中使用的 epics 的最新版本: https://gist.github.com/onderonur/e55f841188263fca5ddd111d218fd505