forkEpic, наблюдаемый редукс 1.0.0-alpha.2, машинопись - PullRequest
0 голосов
/ 21 мая 2018

У меня есть одна эпопея

type GetRailwaysEpic = Epic<GetRailwaysActions, AppState>;

const getRailwaysEpic: GetRailwaysEpic = (action$, state$) =>
  action$.pipe(
    filter(isActionOf(getRailways.request)),
    switchMap(a =>
      getRailways(state$.value.mileages.filters.date)
        .then(getRailways.success)
        .catch(getRailways.failure)
    )
  );

, когда я вызываю куда-нибудь actions.getRailways.request (), она работает как положено (сначала выполняется запрос REQUEST, затем - SUCCESS of FAILURE)

У меня есть другойepic

const initEpic: Epic<FiltersActions, AppState> = (action$, state$) =>
  action$.pipe(
    filter(isActionOf(init)),
    switchMap(({ payload: { date, depotId, locTypeId, railwayId } }) =>
      of(selectDate(date)).pipe(
        concat(
          forkEpic(getRailwaysEpic, state$, getRailways.request())
        )
      )
    )
  );

моя функция ForkEpic:

function forkEpic<T extends Action, S>(
  epicFactory: Epic<T, S>,
  state$: StateObservable<S>,
  ...actions: T[]
) {
  const actions$ = ActionsObservable.of(...actions);
  return epicFactory(actions$, state$, null);
}

Что я хочу: действие 'init' -> действие 'selectDate' -> действие 'getRailways.request' -> 'getRailways.успех »|действие 'getRailways.failure'

Что я вижу: действие 'init' -> действие 'selectDate' -> 'getRailways.success' |Действие «getRailways.failure»

Действие «getRailways.request» где-то отсутствует.Что я делаю не так?

PS getRailways - это функция, которая возвращает обещание PPS. Я нашел подобный вопрос здесь Как связать асинхронные действия и ждать результата без store.dispatch Но этоне то, что я на самом деле ищу.

1 Ответ

0 голосов
/ 23 мая 2018

Таким образом, проблема заключается в том, что функция forkEpic вызывает getRailwaysEpic локально, и, поскольку она использует switchMap, она проглатывает действие «запрос», таким образом не позволяя ему достичь epicMiddleware.

Лучшее решение - объединить действие "select" с потоками действий "request" и вернуть его так, чтобы оно корректно передавалось epicMiddleware обратно в хранилище, а затем оно было перехвачено и обработано getRailwaysEpic из потока действия $.

Вот рабочее решение в кодовой песочнице: https://codesandbox.io/s/375z2qwv1

Вот ответственный код:

const requestEpic = action$ =>
  action$.pipe(
    filter(a => a.type === 'request'),
    switchMap(a => from(makeRequest()).pipe(map(success)))
  );

const initEpic = action$ =>
  action$.pipe(
    filter(a => a.type === 'init'),
    concatMap(a => of(select(), request()))
  );

const rootEpic = combineEpics(requestEpic, initEpic);
const epicMiddleware = createEpicMiddleware(rootEpic);

// 1
// store.dispatch(init());
// should be:
// init -> select -> request -> success

// 2
// store.dispatch(request());
// should be:
// request -> success
...