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