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?