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



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

如果当前正在获取同一部电影,我不想获取该电影。我只是将selectIsFetchingMovieById(action.movieId)选择器传递给自定义中间件。如果它返回true,它不会向化简器传递任何东西。但是当选择器返回false时,它会获取电影,像任何常规的基于承诺的获取数据过程一样运行.then.catch

但是当我使用redux-observable时,给定电影ID的isFetching状态已经是true了。因为减速器已经得到了({type: FETCH_MOVIE_REQUEST, movieId: "10" })动作。选择器始终返回true

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

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

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.我已经有REQUESTSUCCESSERRORCANCELLED。还有很多其他的还原器和史诗。因此,与运营商保持简单可能是一个不错的选择:)

谢谢!

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

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

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

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

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

以下是我与分组解决方案一起使用的最新版本的史诗: https://gist.github.com/onderonur/e55f841188263fca5ddd111d218fd505

最新更新