很好的问题。重要的一点是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
这可能会导致奇怪的错误,即使不是,通常最好的做法是只采用您需要的内容。
We use takeUntil
取消等待FETCH_SUCCESS
如果我们收到FETCH_ERROR
first.
作为奖励,如果您决定也想根据错误进行一些分析,不仅可以重新开始,还可以使用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)
);