Я новичок в реактивном программировании. Просто пытаюсь понять наблюдаемые и операторы rxjs. У меня есть приложение react-redux
, которое имеет специальное промежуточное программное обеспечение для обработки кэшированных данных и флаги isFetching
. Хотя он обрабатывает только те вещи, которые мне нужны, он может быть сложным для таких вещей, как отмена или отмена. Итак, я хотел перенести это приложение на redux-observable
.
Я хочу не получать тот же фильм, если он загружается в данный момент. Я просто передаю селектор selectIsFetchingMovieById(action.movieId)
пользовательскому промежуточному ПО. Если он возвращает true
, он ничего не передает редукторам. Но когда селектор возвращает false
, он выбирает фильм, проходит либо .then
, либо .catch
, как и любой другой процесс извлечения данных на основе обещаний.
Но когда я использую redux-observable
, isFetching
состояние для данного идентификатора фильма уже true
. Потому что редуктор уже получил действие ({type: FETCH_MOVIE_REQUEST, movieId: "10" })
. Селектор всегда возвращает true
.
Если я использую switchMap
, он отменяет предыдущий запрос, даже если у него другой идентификатор фильма. exhaustMap
не будет запускать следующий запрос, даже если у него другой идентификатор фильма и т. Д.
Теперь у меня есть этот эпос. Это работает для 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 или любой другой метод, чтобы выполнить это? Я не хочу добавлять дополнительный actionType, например FETCH_MOVIE_TOGGLE_LOADING
. У меня уже есть REQUEST
, SUCCESS
, ERROR
и CANCELLED
. И много других редукторов и эпопей. Таким образом, простота использования операторов может быть хорошим вариантом:)
Спасибо!