我如何才能仅在另一个史诗未运行时使Redux可观察的史诗才能继续

时间:2020-04-16 22:22:40

标签: javascript rxjs redux-observable

我基本上希望拥有史诗:

  1. 史诗A-当REQUEST_A出现时,发出动作EPIC_A_STARTED,经过一段不确定的时间(异步动作),发出动作EPIC_A_END
  2. Epic B-当REQUEST_B出现时,如果Epic A尚未启动,请继续,直到EPIC_A_END完成。

理想情况下,两个史诗在运行时都将等待其替换完成,因此一次仅出现一个。

感觉就像我需要一个计数器在EPIC_A_STARTED发生时增加,在EPIC_A_COMPLETED发生时减少,但是我不确定如何继续。

如果我们能有一个像这样的伪代码的运算符,那就太好了

// Operator we are trying to write
const waitForActionsToComplete = (startAction, endAction) => {
   // Not sure how to structure this so that it waits for there to be equal of both actions passing through
}


// Epic A
const EPIC_A_FILTER = (action$, state$) =>
  action$.pipe(
    of(actions.REQUEST_A),
    waitForActionsToComplete(actions.EPIC_B_START, actions.EPIC_B_END),
    mergeMap(() => { type: actions.EPIC_A_START }));

const EPIC_A_PROCESS = (action$, state$) =>
  action$.pipe(
    of(actions.EPIC_A_START),
    ...async task,
    mergeMap(() => { type: actions.EPIC_A_END }));


// Epic B
const EPIC_B_FILTER = (action$, state$) =>
  action$.pipe(
    of(actions.REQUEST_B),
    waitForActionsToComplete(actions.EPIC_A_START, actions.EPIC_A_END),
    mergeMap(() => { type: actions.EPIC_B_START }));

const EPIC_B_PROCESS = (action$, state$) =>
  action$.pipe(
    of(actions.EPIC_B_START),
    ...async task,
    mergeMap(() => { type: actions.EPIC_B_END }));

1 个答案:

答案 0 :(得分:0)

您可以使用scan对请求开始操作进行排队,并且仅在史诗般的结束操作之后才出队。我写了一些伪代码:

action$.pipe(
    of(actions.REQUEST_A, actions.REQUEST_B, actions.EPIC_A_END, actions.EPIC_B_END),
    scan(({queue}, current) => {
      if (current is epic end action)
        if (queue is not empty) {
          return { queue: queue.slice(1), triggerEpic: EPIC_A_START or EPIC_B_START depending on queue[0]  }
        }
        else {
          return { queue, triggerEpic: null };
        }
      }
      else {
        if (queue is not empty) {     
          return { queue: [...queue, current], triggerEpic: null };
        }
        else {
          return { queue: [], triggerEpic: EPIC_A_START or EPIC_B_START depending on current }; 
        } 
      } 
    }, { queue: [], triggerEpic: null }),
    filter(x => x.triggerEpic !== null),
    map(x => x.triggerEpic)
)
相关问题