Ordering Behavior in NgRx Effects
Yes, mergeMap causes non-deterministic action ordering under high concurrency. While mergeMap preserves the order of emissions within a single inner observable, it allows multiple HTTP requests to run in parallel. Because network latency varies, a request dispatched second may complete before a request dispatched first. This results in "race conditions" where the state is updated in the order of server response rather than the order of user initiation.
The Impact on Latency and State
The observed "latency spikes" in mergeMap scenarios are typically not caused by the operator itself, but by the resulting state instability. When responses arrive out of order, the UI may flicker between old and new data, or a slower, stale response may overwrite a newer one, creating a perceived lag or inconsistency in the application state.
Switching to concatMap
Switching to concatMap eliminates non-deterministic ordering by serializing the requests. It waits for the current HTTP observable to complete before subscribing to the next one. This ensures that success/failure actions are dispatched in the exact order the original actions were triggered.
Trade-off: While concatMap preserves correctness, it can increase total latency for the final request in a queue, as each request must wait for all preceding requests to finish.
Implementation Steps for Order Preservation
- Identify the Effect: Locate the NgRx Effect handling the concurrent HTTP calls.
- Replace the Operator: Change
mergeMap to concatMap to enforce a first-in, first-out (FIFO) queue.
- Verify Reducer Idempotency: Ensure your reducer handles the resulting actions predictably, regardless of the time elapsed between them.
Verification Method
To isolate whether latency is caused by the network or the NgRx pipeline, use the following verification approach:
- NgRx DevTools: Compare the timestamps of the
Trigger Action and the Success Action.
- Network Throttling: Use Chrome DevTools to simulate "Slow 3G." If
mergeMap is used, you will see responses arriving out of sequence; with concatMap, they will arrive sequentially regardless of individual request speed.
Missing Diagnostic Detail: To further refine this recommendation, please clarify if your reducers perform heavy data transformation or if you are using ChangeDetectionStrategy.OnPush, as these can introduce UI rendering latency that mimics state update lag.