Redux-Observable - 调度必须按顺序 运行 的多个操作

Redux-Observable - Dispatch multiple actions that have to be run in sequence

使用 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;
      } )
   )
}

在操作 SET 的减速器中,我希望序列是有序的,无论上面 setTimeout 的随机性如何,因为 flatMap 正在返回承诺。结果应该是这样的:

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 类型的操作按顺序排列在流中。一个动作在执行之前等待另一个动作完成。

对于flatMap,内部可观察对象的所有发射都按照它们发生的顺序转发到外部可观察对象。现在,对于 Promise,只有在 Promise 解析时才会创建发射,而不是立即创建。因此,您会收到超时创建的 "random" 订单。

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

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