Как сделать EPIC полностью динамичным

Я использую angular 2 с redux/store вместе с redux-observable для формирования эпиков. То, что я хочу сделать, - это общий опросчик, поэтому мне нужно написать опросник только один раз. У меня есть около 25 сервисов, и я бы предпочел, чтобы действие проходило в том, какой тип действий и сервисов он будет выполнять, а затем иметь дублирующийся код и писать огромный случай или операторы if:

код, который у меня есть до сих пор:

startPoller: Epic<Action<void>, Action<void>> = action$ =>
    action$.ofType(BankActions.DEPOSIT.POLL_DATA)
      .switchMap(action =>
        Observable.interval(1000)
          .takeUntil(action$.ofType(BankActions.DEPOSIT.STOP_POLLING))
          .mergeMap(count =>
            this.bankService.getDeposit.(action.payload)
              .map(payload => ({ type: BankActions.DEPOSIT.POLL_SUCCESS, payload }))
              .catch(error => Observable.of({
                type: BankActions.DEPOSIT.POLLING_FAILED,
                payload: error
              }))
        )
)

Что я хочу сделать в псевдокоде:

startPoller: Epic<Action<void>, Action<void>> = action$ =>
    action$.ofType(BankActions.DEPOSIT.POLL_DATA || BankActions.WITHDRAW.POLL_DATA || InvestActions.STOCK_PRICE.POLL_DATA )
      .switchMap(action =>
        Observable.interval(1000)
          .takeUntil(action$.ofType(action.STOP_POLLING))
          .mergeMap(count =>
            this.bankService.getDeposit(action.payload)
              .map(payload => ({ type: BankActions.DEPOSIT.POLL_SUCCESS, payload }))
              .catch(error => Observable.of({
                type: BankActions.DEPOSIT.POLLING_FAILED,
                payload: error
              }))
        )
)

Я предполагаю, что для того, чтобы это сработало, мне может потребоваться создать какой-то тип базового типа, который будет расширяться для каждого действия/службы, требующей опроса, тогда я мог бы просто проверить, если это тип «PollerService» или тип «PollerEpic», а затем Я могу отфильтровать это?


person Mickey Sly    schedule 01.11.2017    source источник


Ответы (1)


Немного неясно, о чем вы спрашиваете, но я думаю, что могу ответить на несколько вещей.

Ваш псевдокод ofType:

action$.ofType(BankActions.DEPOSIT.POLL_DATA || BankActions.WITHDRAW.POLL_DATA || InvestActions.STOCK_PRICE.POLL_DATA )

Можно выполнить, передав их в качестве аргументов; ofType проверит, относится ли данное действие к какому-либо из этих типов.

action$.ofType(BankActions.DEPOSIT.POLL_DATA, BankActions.WITHDRAW.POLL_DATA, InvestActions.STOCK_PRICE.POLL_DATA )

Следующее, что я вижу в вашем псевдокоде, это то, что вы хотите, чтобы сопоставленное действие предоставляло тип STOP_POLLING.

.takeUntil(action$.ofType(action.STOP_POLLING))

Неясно, какие значения для STOP_POLLING приемлемы, обычно переменные типа redux должны называться так же, как и строка, например. STOP_POLLING = 'STOP_POLLING' в этом случае это не имеет значения, так как все они будут иметь одинаковое значение 'STOP_POLLING'.

Если вы хотите, чтобы они различались, я бы не стал использовать соглашение UPPER_CASE, потому что это может запутать его в обслуживании:

// what an action _might_ look like
{
  type: BankActions.DEPOSIT.POLL_DATA,
  meta: {
    stopType: 'DEPOSIT_STOP_POLLING'
  }
}

// then used something like this:
.takeUntil(action$.ofType(action.meta.stopType))
person jayphelps    schedule 02.11.2017