代码之家  ›  专栏  ›  技术社区  ›  Josh Mc

我怎么能让一个redux可观察的史诗只有在另一个史诗没有运行时才能继续

  •  0
  • Josh Mc  · 技术社区  · 6 年前

    我基本上是在寻找史诗:

    1. Epic B-当请求_B进入时,如果Epic A没有启动继续,否则等待Epic_A_END完成。

    感觉我需要一个计数器来增加EPIC_a_启动时的增量和EPIC_a_完成时的递减,但我不确定如何继续。

    如果我们能有一个类似psuedo代码的操作员就好了:

    // 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 }));
    
    
    0 回复  |  直到 6 年前
        1
  •  0
  •   NickL    6 年前

    你可以利用 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)
    )