如何在Redux Observable中调度一个动作,等待一秒钟,然后再调度两个动作?

时间:2019-12-05 02:17:15

标签: redux rxjs redux-observable

我如何在单个史诗中执行以下操作

  1. 调度pauseGame()
  2. 等待1秒
  3. 发送2个动作

以下内容调度最后两个动作,但不调度pauseGame()。

enter image description here

const moveEpic: RootEpic = (action$, state$) =>
  action$.pipe(
    filter(isActionOf(move)),
    map(() => pauseGame()),
    filter(() => state$.value.ruleRow.lastMoveSuccessful),
    delay(1000),
    switchMap(() => [
      removeBoardObject(
        state$.value.ruleRow.totalMoveHistory[state$.value.ruleRow.totalMoveHistory.length - 1]
          .dragged,
      ),
      resumeGame(),
    ]),
  );

1 个答案:

答案 0 :(得分:1)

pauseGame未调度的原因是因为您未调度。您要呼叫操作创建者,然后立即将可观察状态更改为lastMoveSuccessful

相反,您想要的是拆分管道并将它们merge还原为一个。我知道这很令人困惑,但这就是Redux-Observable目前的工作方式。如果您想以其他方式随时分配,请查看我的文章:https://dev.to/sawtaytoes/the-best-practice-anti-pattern-jj6

发生move类型时,切换到新的可观察对象。该可观察值是2个新可观察值的合并:一个立即发送pauseGame,另一个可检查最后一次移动是否成功,如果是,则等待一秒钟并发送另外2个动作。

const moveEpic: RootEpic = (action$, state$) => (
  action$.pipe(
    filter(isActionOf(move)),
    switchMap(() => (
      merge(
        of(pauseGame()),
        of(state$.value.ruleRow.lastMoveSuccessful).pipe(
          filter(Boolean),
          delay(1000),
          concatMap(() => [
            removeBoardObject(
              state$.value.ruleRow.totalMoveHistory[
                state$.value.ruleRow.totalMoveHistory.length - 1
              ].dragged
            ),
            resumeGame(),
          ]),
        )
      )
    )),
  );
)

作为旁注,我不知道您为什么创建自己的isActionOf函数,但是通常您应该能够将该行更改为ofType(move)

Evert Bouw利用startWithendWith提供了一个更简单的建议。您将失去管道中的顺序排序,但不必拆分它:

const moveEpic: RootEpic = (action$, state$) => (
  action$.pipe(
    filter(isActionOf(move)),
    switchMap(() => (
        of(state$.value.ruleRow.lastMoveSuccessful).pipe(
          filter(Boolean),
          delay(1000),
          map(() => (
            removeBoardObject(
              state$.value.ruleRow.totalMoveHistory[
                state$.value.ruleRow.totalMoveHistory.length - 1
              ].dragged
          )),
          startWith(pauseGame()),
          endWith(resumeGame()),
        )
      )
    )),
  );
)

请记住,如果您需要了解state$endWith的值,则可以改用finalize。它使用函数而不是值。

相关问题