很好的问题。重要的是,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”,这可能会引起奇怪的错误,即使没有问题,也最好只拿自己需要的东西。
我们使用“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)
);
take(1)
。这基本上意味着在第一个“PAGINATION_CLICKED”之后,“序列”被忽略了。非常感谢,对于该库提供了很好的支持 :) - Matt Derrick