【问题标题】:Redux-Observable - Dispatch multiple actions that have to be run in sequenceRedux-Observable - 分派多个必须按顺序运行的操作
【发布时间】:2018-08-22 16:54:23
【问题描述】:

使用 redux-observable,我试图从单个史诗中产生多个 WORK 动作,如下所示:

( action$, state$ ) => {
   return action$.pipe(
      ofType( 'SPAWN' ),
      flatMap( action => {
         return [
            { type: 'WORK', payload: 'a' },
            { type: 'WORK', payload: 'b' },
            { type: 'WORK', payload: 'c' },
         ];
      } )
   )
}

动作触发良好,但问题是,这些 WORK 动作是异步的,因此它们由另一个史诗处理,如下所示:

( action$, state$ ) => {
   return action$.pipe(
      ofType( 'WORK' ),
      flatMap( action => {
         const promise = new Promise( resolve => {
            setTimeout( () => {
               resolve( { type: 'SET', payload: action.payload } );
            }, Math.random() * 5000 ); // promise may resolve at different times
         } );

         return promise;
      } )
   )
}

在reducer for action SET,我希望,不管上面setTimeout 的随机性如何,序列都是有序的,因为flatMap 正在返回promise。结果应该是这样的:

a
b
c

尽管如此,我得到了 SET 操作的随机排序,例如:

b
c
a

如果有人能指出正确的方向并帮助我理解,我将不胜感激。

工作更新 根据@Oles Savluk 的回答,我将WORK 史诗编辑为如下:

( action$, state$ ) => {
   return action$.pipe(
      ofType( 'WORK' ),
      concatMap( action => {
         const promise = new Promise( resolve => {
            setTimeout( () => {
               resolve( { type: 'SET', payload: action.payload } );
            }, Math.random() * 5000 ); // promise may resolve at different times
         } );

         return promise;
      } )
   )
}

注意concatMap 的使用使得WORK 类型的动作按顺序排列在流中。一个动作在执行之前等待另一个动作完成。

【问题讨论】:

    标签: angular rxjs observable ngrx redux-observable


    【解决方案1】:

    您需要使用concatMap operator,它将按顺序发出项目,而不是flatMap(mergeMap),后者同时执行此操作

    如果您是 Rx 新手,可以阅读 this article 以了解展平运算符之间的区别。

    【讨论】:

    • 这个concatMap 应该用在SPAWN 史诗还是WORK 史诗中?在我看来,一旦你调度了常见的 Redux 动作,它就超出了 Rx 的控制范围。因此,WORK 史诗没有遵循 Promise 的正确解析顺序。
    • 感谢@Oles Savluk,我终于明白您使用concatMap 的意思了。它应该在WORK 史诗中使用。基本上,当我们使用concatMap 时,我们想说的是我知道我们有一些这样的动作,但不要一概而论,而是一个接一个地执行它们.
    【解决方案2】:

    使用flatMap,内部可观察对象的所有发射都按其出现的顺序转发到外部可观察对象。现在,使用Promise,该发射仅在 Promise 解决时创建,而不是立即创建。因此,您会收到超时创建的“随机”订单。

    【讨论】:

    • 感谢@ggradnig 指出这一点。在这方面我的情况有什么解决方案吗?
    猜你喜欢
    • 1970-01-01
    • 2017-02-01
    • 2017-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多