【问题标题】:How can I only enable an redux-observable epic to continue only when another epic is not running仅当另一个史诗未运行时,我如何才能仅使 redux-observable 史诗继续
【发布时间】:2020-04-16 22:22:40
【问题描述】:

我基本上是在寻找史诗:

  1. Epic 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 }));

【问题讨论】:

    标签: javascript rxjs redux-observable


    【解决方案1】:

    您可以使用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)
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-13
      • 2019-01-23
      • 2017-04-22
      • 1970-01-01
      • 2020-12-30
      • 1970-01-01
      • 2017-05-06
      • 2020-06-03
      相关资源
      最近更新 更多