【问题标题】:Wait for sequence of action with a Redux Observable等待 Redux Observable 的操作序列
【发布时间】:2018-01-14 17:30:53
【问题描述】:

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

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

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

如果触发另一个 FETCH_ERROR 类型的操作,我也想取消并重新开始该序列。

【问题讨论】:

    标签: redux redux-observable


    【解决方案1】:

    很好的问题。重要的一点是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 时,我们都会开始监听内部的 Observable 链,该链监听单个 FETCH_SUCCESS。拥有.take(1) 很重要,因为否则我们会继续收听多个FETCH_SUCCESS,这可能会导致奇怪的错误,即使不是,通常也是最好的做法,只取你需要的东西。

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


    作为奖励,如果您决定也要根据错误进行一些分析,不仅要重新开始,您还可以使用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)
      );
    

    【讨论】:

    • 我快到了!我以您的第一个示例结束,但没有(现在显然很关键)take(1)。这基本上意味着在第一个“PAGINATION_CLICKED”之后忽略了“序列”。非常感谢您对图书馆的大力支持:)
    • 有没有一种方法可以表明我希望在产生第三个动作之前调用/完成这两个动作?
    • 编辑:nvm,我想我用 zip 运算符解决了这个问题。
    • 改变生活的秘诀!
    • 在您的第一个代码示例中使用 exaustMap 而不是 switchMap 不是更好吗?如果方法 analyticsAction() 需要一些时间并且我们同时收到 pagination_clicked 操作,它将取消方法 analyticsAction()
    猜你喜欢
    • 1970-01-01
    • 2018-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 2019-02-01
    • 2020-01-17
    相关资源
    最近更新 更多