在一种情况下,我有两个动作:
INITIATE
(在单击按钮时触发),FETCH_SUCCESS
(在通过页面加载调用的AJAX请求以状态存储数据时触发)。
史诗般的处理INITIATE
动作要求来自FETCH_SUCCESS
的数据在该状态下可用。
我如何编写此史诗,以便使其能够:1)正常运行其逻辑,在FETCH_SUCCESS
运行一次之后,其被点击的次数为两次;以及2)如果在FETCH_SUCCESS
之前单击,等待FETCH_SUCCESS
发生,然后在数据可用/执行成功操作后继续执行逻辑。
我可以想到至少有一些简单的方法可以解决此问题,但不希望用单个rxjx史诗可以实现。例如:1)失败/重试流程,其中史诗仅检查数据是否可用,如果不可用,则以较小的延迟递归调用自身。 2)如果INITIATE
尚未运行,请在状态下将FETCH_SUCCESS
设置为标志,然后听FETCH_SUCCESS
并将其踢起INITIATE
(如果设置了此标志)它何时运行。
我想出的唯一不包含这两种方法的方法是将其写入两个史诗中:
在FETCH_SUCCESS
之前处理INITIATE
的版本(快乐路径)如下:
export const initiateFirstEpic = action$ => action$
.ofType(INITIATE)
.skipUntil(Observable.of(FETCH_SUCCESS))
.map(action => {
return LogicAction();
});
另一个处理点击速度太快,使得INITIATE
发生在FETCH_SUCCESS
之前:
export const successFirstEpic = action$ => action$
.ofType(INITIATE)
.switchMap(() =>
action$.ofType(FETCH_SUCCESS)
.take(1)
.map(action => {
return LogicAction();
})
);
这似乎行不通,也不是我想要的那样。是否有实现此目标的好方法?我对RxJS和Redux Observable还是很陌生,所以答案可能很明显。
答案 0 :(得分:1)
我认为您正在寻找的是combineLatest。
export const initiateEpic = action$ => Observable
.combineLatest(action$.ofType(INITIATE), action$.ofType(FETCH_SUCCESS).take(1))
.map(([action, _]) => {
return LogicAction();
});
可以选择在take(1)
动作FETCH_SUCCESS
上使用ofType
,以防止每次获得LoginAction
时产生FETCH_SUCCESS
答案 1 :(得分:0)
这里是基于@ m1ch4ls的版本,但改用了运算符:
const initiateEpic = action$ =>
action$
.combineLatest(action$.ofType(FETCH_SUCCESS).take(1))
.map(([initiateAction, fetch_success_action]) => {
return LogicAction();
});
最初,我不知道有一个静态函数Observable.combineLatest(obs1$, obs2$)
和一个运算符obs1$.combineLatest(obs2$)
,因此我对@ m1ch4ls的评论回答了。