等待第二次异步操作,然后继续进行可观察到的Redux

时间:2018-08-07 14:47:16

标签: rxjs redux-observable

在一种情况下,我有两个动作:

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还是很陌生,所以答案可能很明显。

2 个答案:

答案 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的评论回答了。