I'm running Composable Architecture 0.13.0 on iOS 14.2, and I'm experiencing an unexpected order of actions processed by the following reducer:
let reducer = Reducer<State, Action, Void> { state, action, _ in
let result: Effect<Action, Never>
switch action {
case .a, .b, .c:
result = .none
case .d:
result = .concatenate(
.init(value: .a),
.init(value: .b)
)
case .x:
result = .concatenate(
.init(value: .d),
.init(value: .c)
)
// Received: .x, .d, .c, .a, .b
}
return result
}.debug()
When I send .x
action to a view store with such a reducer, I receive .x, .d, .c, .a, .b
sequence of events printed in console.
Note that for some reason .c
precedes .a, .b
, which is not what I would expect. My expectation is that .a, .b
should precede .c
, since .a, .b
are concatenated into .d
, which precedes .c
.
If handling of .x
case is rewritten to the following:
case .x:
result = Publishers.Sequence(sequence: [.d, .c])
.eraseToEffect()
// Received: .x, .d, .c, .a, .b
I'm getting the same .x, .d, .c, .a, .b
.
And only if the latter is amended to this:
case .x:
result = Publishers.Sequence(sequence: [.d, .c])
.receive(on: DispatchQueue.main)
.eraseToEffect()
// Received: .x, .d, .a, .b, .c
I'm getting the expected .x, .d, .a, .b, .c
.
Is there any explanation of such behavior?