0

我正在尝试创建一个将采取行动的史诗,然后调度两个不同的行动,第二个行动延迟两秒。经过一堆尝试,这是我能做的最好的:

const succeedEpic = action$ =>
  action$.filter(action => action.type === 'FETCH_WILL_SUCCEED')
    .mapTo({ type: 'FETCH_REQUEST' })
    .merge(Observable.of({ type: 'FETCH_SUCCESS' }).delay(2000))

不幸的是,似乎:

Observable.of({ type: 'FETCH_SUCCESS' }).delay(2000)

在我的应用程序加载后立即运行(而不是在事件从父流中下来时)。我注意到了这一点,因为FETCH_SUCCESS在我的应用程序加载后两秒钟,reducer 就收到了这个动作。我什至附上了一个console.log来确认这一点:

const succeedEpic = action$ =>
  action$.filter(action => action.type === 'FETCH_WILL_SUCCEED')
    .mapTo({ type: 'FETCH_REQUEST' })
    .merge(Observable.of({ type: 'FETCH_SUCCESS' })
           .do(() => console.log('this has begun'))
           .delay(2000)
          )

“这已经开始”在应用程序启动时记录到控制台。

我怀疑这与 Redux-Observable 如何为您自动订阅有关。

期望的行为是我将:

  1. 单击调度FETCH_WILL_SUCCEED事件的按钮。
  2. 立即,一个FETCH_REQUEST事件被分派。
  3. 两秒后,一个FETCH_SUCCESS事件被分派。
4

2 回答 2

2

事实证明,我需要将两个事件都包装在一个mergeMap. 感谢 RxJS Gitter 频道上的@dorus 提供了这个答案。

这是我的工作结果:

const succeedEpic = action$ =>
  action$.filter(action => action.type === 'FETCH_WILL_SUCCEED')
    .mergeMapTo(Observable.of({ type: 'FETCH_REQUEST' })
      .concat(Observable.of({ type: 'FETCH_SUCCESS' })
        .delay(1000)))

merge应该可以代替concat,但我认为concat语义更好。

于 2017-02-19T19:42:39.433 回答
0

可能有更优雅的解决方案,但为什么不直接使用 2 个史诗并将它们组合起来呢?

第一个分派获取请求:

const onFetchWillSucceed = action$ => action$.ofType('FETCH_WILL_SUCCEED')
  .mapTo({ type: 'FETCH_REQUEST' })

第二个等待 2 秒并发送成功:

const onFetchRequest = action$ => action$.ofType('FETCH_REQUEST')
  .delay(2000)
  .mapTo({ type: 'FETCH_SUCCESS' })

最后它们只是组合成一部史诗

const both = combineEpics(onFetchWillSucceed, onFetchRequest)
于 2017-02-19T14:32:40.393 回答