Как создать эпос, который испускает другой и в то же время слушает его конец только один раз и до тех пор, пока он не провалится? - PullRequest
0 голосов
/ 08 июля 2019

Мне нужно создать Epic A, который будет испускать Action B, таким образом запуская Epic B, который будет выполнять некоторые асинхронные действия и, в конце, испускать Action C, и в то же время Epic A устанавливает слушателя для Action C и когда он получен, он испускает действие D, таким образом заканчивая прослушивание действия C, пока не будет вызвано снова. Также ... если Epic B возвращает действие E (сбой), то Epic A также завершает прослушивание действия C.

1 Ответ

0 голосов
/ 08 июля 2019
import { mergeMap, map, take, takeUntil, withLatestFrom } from 'rxjs/operators';
import { merge, of } from 'rxjs';
import { ofType } from 'redux-observable';

const smth = ($action, $state) =>
  $action.pipe(
    ofType('action-a'),
    withLatestFrom($state),
    mergeMap(([action, state]) => {
      const someData = someSelector(state);

      return merge(
        of({ type: 'action-b', someData }),
        $action.pipe(
          ofType('action-c'),
          map(() => {
            return {
              type: 'action-d',
            };
          }),
          take(1),
          takeUntil($action.pipe(ofType('action-e')))
        )
      );
    })
  );

export default smth;

В приведенном выше коде мы создаем экземпляр epic, который будет запускать его содержимое при получении action-a. Он также возвращает одно действие и одного слушателя (назовем это Sub-Epic). Действие - action-b, и по завершении оно выдаст либо action-c, либо action-e (сбой) Sub-Epic сам ожидает, что произойдет action-c, мы берем его только один раз и принимаем до тех пор, пока action-e не получим, потому что мы хотим, чтобы action-d произошло только один раз.

Мы запускаем action-d в результате повторного запуска action-a

Чтобы запустить это ... мы можем просто позвонить dispatch({ type: 'action-a' });

...