使用 Redux Observable 等待动作序列
Wait for sequence of action with a 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
类型的另一个动作触发,我也想取消并重新开始该序列。
好问题。重要的一点是 action$
是一个 hot/multicast 所有动作的流,因为它们被分派(它是一个主题)。由于天气很热,我们可以将其组合多次,它们都将收听相同的动作流。
// 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
,这可能会导致奇怪的错误,即使不是通常最好的做法也是只获取您需要的内容。
如果我们先收到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)
);
我有一个用例,在使用 Redux Observables 分派另一个操作之前,我需要等待一系列操作。我见过一些类似的问题,但我无法理解如何将这些方法用于给定的用例。
本质上我想做这样的事情:
action$
.ofType(PAGINATION_CLICKED) // This action occurred.
.ofType(FETCH_SUCCESS) // Then this action occurred after.
.map(() => analyticsAction()); // Dispatch analytics.
例如,如果 FETCH_ERROR
类型的另一个动作触发,我也想取消并重新开始该序列。
好问题。重要的一点是 action$
是一个 hot/multicast 所有动作的流,因为它们被分派(它是一个主题)。由于天气很热,我们可以将其组合多次,它们都将收听相同的动作流。
// 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
,这可能会导致奇怪的错误,即使不是通常最好的做法也是只获取您需要的内容。
如果我们先收到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)
);