마지막 검색이 먼저 도착한다면

Latest Request Wins

응답 순서가 뒤집혀도 사용자의 최신 의도를 화면에 유지합니다.

GitHub에서 원문 보기 ↗새 탭

TRY THE FAILURE CASE

먼저 보낸 요청이 늦게 끝난다면?

LIVE PREVIEW
01 / 먼저 보낸 요청

A · “layout”

02 / 최신 요청

B · “motion”

현재 검색 · motion

B의 응답을 기다리고 있어요.

B를 먼저 완료한 뒤 A를 완료해 보세요.

응답 순서를 직접 바꾸는 로컬 시뮬레이션입니다.

원문 가이드 ENGLISH

Repository Boundary

Prevent an older read response from replacing the result of a newer user intent. This pattern belongs to Design Engineering and adds no Layout CSS or shared store implementation.

Reusable Method

Use for replaceable reads such as search and selected-item detail. Do not use this policy to discard the outcomes of independent writes that all matter.

State Model And Ownership

The read owner stores a monotonically increasing identity, status, and last accepted result. Both success and failure must match the current request. Cancellation is an optional resource optimization; identity decides acceptance.

Transitions

Event and precondition Next state Effect or invariant
Start read Pending with new ID Previous IDs lose authority
Matching success Ready with results Accept only current intent
Matching failure Error Preserve or clear old results under explicit policy
Stale success or failure Unchanged No status, result, or error mutation
Dispose Disposed and invalidated Ignore all pending outcomes

Minimal Executable Example

Run this standalone JavaScript block with Node.js 22 or newer, or run all pattern examples from a repository checkout with npm run test:state-management. The assertions exercise the local model, not a browser or backend.

import assert from "node:assert/strict";
let serial = 0, active = 0, status = "idle", result = null;
const begin = () => { active = ++serial; status = "pending"; return active; };
function settle(id, ok, value) {
  if (id !== active) return;
  status = ok ? "ready" : "error";
  if (ok) result = value;
}
const a = begin(), b = begin();
settle(b, true, "B");
settle(a, true, "A");
settle(a, false, "old failure");
assert.equal(result, "B");
assert.equal(status, "ready");
const c = begin();
active = ++serial; status = "disposed";
settle(c, true, "C");
assert.equal(status, "disposed");

What Breaks If Removed

Remove the ID check: resolve B then A and the screen displays A under B's query. Guarding success only still allows A's error or finally handler to clear B's pending status.

Composition And Substitution

Combine URL state for committed query inputs and ID selection for detail. Use single flight for duplicate writes rather than silently discarding their acknowledgements.

Opinionated Guidance

Choose whether old results stay visible while refreshing and label their query identity. Debouncing reduces starts but does not establish response ordering.

Platform-Specific Guidance

Check identity after each awaited stage, including body decoding or transformations. Dispose invalidation and listener cleanup belong to the framework adapter.

Unsupported Absolutes

Latest-wins prevents this local overwrite; it does not guarantee fresh server data, cache coherence, or distributed consistency.

Verification Contract

  • Start A then B; resolve B then A, including an A failure.
  • Start B while A is pending; A completion must not clear B's pending indicator.
  • Dispose before completion; no displayed state may update.

Record actual outcomes separately using the verification matrix.

Source, License, And Attribution

Locally authored synthesis and examples. No upstream implementation is copied. These experimental contracts describe consumer-owned behavior; review when a failure, ownership change, or platform change invalidates an assumption.

IA Navigation

Parent: State Management. Next: Continue the state management route.