等待Redux Observable的操作序列

时间:2017-08-07 11:59:47

标签: redux redux-observable

我有一个用例,在使用Redux Observables调度另一个之前,我需要等待一系列操作。我已经看到了一些类似的问题,但我无法理解如何在我给定的用例中使用这些方法。

本质上我想做的事情是这样的:

action$
  .ofType(PAGINATION_CLICKED) // This action occurred.
  .ofType(FETCH_SUCCESS) // Then this action occurred after.
  .map(() => analyticsAction()); // Dispatch analytics.

如果FETCH_ERROR类型的其他操作触发,我还想取消并重新启动该序列。

1 个答案:

答案 0 :(得分:17)

好问题。重要的一点是action$是调度所有操作的热/多播流(它是一个主题)。由于它很热,我们可以将它组合多次,它们都会听取相同的动作流。

// uses switchMap so if another PAGINATION_CLICKED comes in
// before FETCH_SUCCESS we start over

action$
  .ofType(PAGINATION_CLICKED)
  .switchMap(() =>
    action$.ofType(FETCH_SUCCESS)
      .take(1) // <-------------------- very important!
      .map(() => analyticsAction())
      .takeUntil(action$.ofType(FETCH_ERROR))
  );

因此,每当我们收到PAGINATION_CLICKED时,我们就会开始收听侦听单个FETCH_SUCCESS的内部Observable链。拥有.take(1)非常重要,否则我们会继续倾听不止一个FETCH_SUCCESS,这可能会导致奇怪的错误,即使不是通常最好的做法,只能采取你需要的东西。

如果我们先收到takeUntil,我们会使用FETCH_SUCCESS取消等待FETCH_ERROR

作为奖励,如果你决定也想根据错误做一些分析,不仅要重新开始,你可以使用race确实在两个流之间竞争。第一个发射,胜利;另一个是取消订阅。

action$
  .ofType(PAGINATION_CLICKED)
  .switchMap(() =>
    Observable.race(
      action$.ofType(FETCH_SUCCESS)
        .take(1)
        .map(() => analyticsAction()),
      action$.ofType(FETCH_ERROR)
        .take(1)
        .map(() => someOtherAnalyticsAction())
    )
  );

这是同样的事情,但使用race作为实例运算符而不是静态运算符。这是您可以选择的风格偏好。他们都做同样的事情。使用哪一个更清楚。

action$
  .ofType(PAGINATION_CLICKED)
  .switchMap(() =>
    action$.ofType(FETCH_SUCCESS)
      .map(() => analyticsAction())
      .race(
        action$.ofType(FETCH_ERROR)
          .map(() => someOtherAnalyticsAction())
      )
      .take(1)
  );