如何在 Redux Observable 中发送一个动作,等待 1 秒,然后再发送两个动作?

How can I dispatch one action, wait 1 second, then dispatch two more actions in Redux Observable?

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

  1. 调度 pauseGame()
  2. 等待 1 秒
  3. 调度 2 个操作

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

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(),
    ]),
  );

pauseGame 没有调度的原因是你没有调度它。您正在调用动作创建者,然后立即将您的可观察状态更改为 lastMoveSuccessful.

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

当出现move类型时,切换到一个新的observable。该 observable 是 2 个新 observable 的合并:一个立即调度 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()),
        )
      )
    )),
  );
)

请记住,如果您需要知道 endWithstate$ 的值,则需要使用 finalize。它接受一个函数而不是一个值。