我是响应式编程的新手。只是试图理解可观察量和 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
.我已经有REQUEST
、SUCCESS
、ERROR
和CANCELLED
。还有很多其他的还原器和史诗。因此,与运营商保持简单可能是一个不错的选择:)
谢谢!
根据定义,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