Redux-Observable - отправляет несколько действий, которые должны выполняться последовательно

С помощью 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 быть расположены в потоке последовательно. Одно действие ожидает завершения другого перед выполнением.

2 ответа

Решение

Вам нужно использовать concatMap оператор, который будет генерировать элементы последовательно вместо flatMap(mergeMap), которые делают это одновременно

Если вы новичок в Rx, вы можете прочитать эту статью, чтобы понять разницу между сглаживающими операторами.

С flatMapвсе излучения внутренней наблюдаемой направляются к внешней наблюдаемой в порядке их возникновения. Теперь с Promise, эта эмиссия создается только тогда, когда Обещание разрешается, а не сразу. Следовательно, вы получаете "случайный" заказ, созданный по таймауту.

Другие вопросы по тегам