等待Redux Observable的操作序列

Mat*_*ick 16 redux redux-observable

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

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

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

如果另一个类型的动作FETCH_ERROR触发,我还想取消并重新启动该序列.

jay*_*lps 24

好问题.重要的一点是,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))
  );
Run Code Online (Sandbox Code Playgroud)

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

如果先收到的话,用takeUntil取消等候.FETCH_SUCCESSFETCH_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())
    )
  );
Run Code Online (Sandbox Code Playgroud)

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

action$
  .ofType(PAGINATION_CLICKED)
  .switchMap(() =>
    action$.ofType(FETCH_SUCCESS)
      .map(() => analyticsAction())
      .race(
        action$.ofType(FETCH_ERROR)
          .map(() => someOtherAnalyticsAction())
      )
      .take(1)
  );
Run Code Online (Sandbox Code Playgroud)