Подтвердить что ты не робот

Redux-наблюдаемый - отправляет несколько редукционных действий в один эпический

Я ищу способ отправки нескольких действий редукции в одном эпическом программном обеспечении redux-observable.

Предположим, что у меня есть следующий Epic. Каждый раз, когда происходит событие SEARCH, Epic загружает данные из бэкэнд и отправляет RESULTS_LOADED действие.

searchEpic = (action$) => 
    action$
    .ofType('SEARCH')
    .mergeMap(
        Observable
        .fromPromise(searchPromise)
        .map((data) => {
            return {
                type: 'RESULTS_LOADED',
                results: data
            }
        })
    )

Теперь предположим, что мне нужно отправить дополнительные действия, когда разрешен searchPromise.

Самый простой способ сделать это, похоже, второй эпик, который будет слушать RESULTS_LOADED и отправить второе действие. Например:

resultsLoadedEpic = (action$) => 
    action$
    .ofType('RESULTS_LOADED')
    .map(({results} => {
         return {
             type: 'MY_OTHER_ACTION',
             results
         } 
    })

В этом простом примере это довольно просто. Но когда Epics растет, я, как правило, обнаруживаю, что у меня много действий по сокращению, единственной целью которых является запуск других действий. Кроме того, некоторые из кода rxjs необходимо повторить. Я считаю это немного уродливым.

Итак, мой вопрос: есть ли способ отправить несколько действий редукции в один Epic?

4b9b3361

Ответ 1

Нет необходимости устанавливать соотношение "один к одному" в/в. Таким образом, вы можете испустить несколько действий, используя mergeMap (aka flatMap), если вам нужно:

const loaded = (results) => ({type: 'RESULTS_LOADED', results});
const otherAction = (results) => ({type: 'MY_OTHER_ACTION', results});

searchEpic = (action$) => 
    action$
    .ofType('SEARCH')
    .mergeMap(
        Observable
        .fromPromise(searchPromise)
        // Flattens this into two events on every search
        .mergeMap((data) => Observable.of(
          loaded(data),
          otherAction(data))
        ))
    )

Обратите внимание, что любой оператор Rx, который принимает Observable, также может принимать Promise, Array или Iterable; потребляя их, как если бы они были потоками. Таким образом, мы могли бы использовать массив для того же эффекта:

.mergeMap((data) => [loaded(data), otherAction(data)])

Какой из них вы используете, зависит от ваших личных предпочтений и использования.