Romaji to Kana Converter: React & Next.js — Chapter 5, Exercise 2 ===================================================================== TASK Reproduce this chapter's own race condition with real code, using three staggered requests instead of two (an early slow one, a middle- timed fast one, and a late medium-speed one). Verify the latest- request-wins guard still produces the correct final result. SOLUTION Simulating a user typing "s," then "su" 10ms later, then "sus" 20ms after that -- with the three requests given deliberately mismatched artificial latencies (60ms, 5ms, and 20ms respectively) so they don't resolve in the order they were fired: Naive version (no guard): naive applied: su-result <- resolves first (fired 10ms in, 5ms latency) naive applied: sus-result <- resolves second (fired 20ms in, 20ms latency) naive applied: s-result <- resolves LAST (fired at 0ms, but 60ms latency) FINAL (naive): s-result -- WRONG. The user's real last input was "sus." Guarded version (an incrementing latestId, checked when each response arrives): discarded (stale): su-result applied (still latest): sus-result discarded (stale): s-result FINAL (guarded): sus-result -- correct. Even with three overlapping requests instead of two, the guard behaves exactly the same way it did for the chapter's own two-request example: every response still checks "am I still the most recent request that was ever fired?" before it's allowed to update the display. The middle request ("su") resolves first in real time but is correctly discarded the moment the third request ("sus") is fired, since firing a new request immediately bumps latestId forward -- a response doesn't need to have already arrived to invalidate an earlier one, it just needs to no longer be the latest ID. The slowest request ("s") is discarded for the same reason, even though it finishes dead last and would have been the only response left standing under the naive version. WHY THIS WORKS AS AN ANSWER ---------------------------- It extends the chapter's own two-request demonstration to three real, independently-timed requests, confirms the naive version reproduces the identical class of bug at a larger scale, and confirms the guard still recovers the correct final result -- because "latest" is determined by when a request was fired, not by arrival order.