Question presented to candidate: "On our sign-up form, people pick a username and we tell them right away whether it is free. Build that check against a fake API. Do not send a request on every keystroke, and make sure a slow answer for something they typed earlier can never overwrite the answer for what is in the box now."
Requirements:
- Username rules checked locally first: 3 to 16 characters, lowercase letters, digits and underscore. No request is sent for a name that fails them.
- For a valid name, wait until typing pauses (debounce, 400 ms), then call a simulated
checkUsername(name)with variable latency. - Show
Checking availability...,<name> is available,<name> is taken, or a retry message if the request fails, in a polite live region. - Responses for anything other than the current value are ignored, even if they arrive last.
- Sign up is enabled only when the name is confirmed available and the email is valid; then a simulated create call and a welcome message.
What a strong answer should cover:
- Debounce with a timer that is cleared on every change, and why it reduces load and flicker.
- The race condition: two requests in flight, the older one answers last. Fix it with a per-request staleness flag or request id (cleanup), and optionally by tagging each result with the name it answers.
- Deriving the visible status from the current value and the latest result, instead of storing status strings.
- Cancelling:
clearTimeoutfor the pending timer, andAbortControllerorswitchMapfor in-flight requests; a Promise itself cannot be cancelled. - Accessibility (
aria-live="polite"for the status,aria-describedbyon the input) and why the server must still re-check at submit.
Clarifying questions expected:
- "Is the check case-insensitive, and are usernames normalized before checking?"
- "Should we cache answers for names already checked?"
- "What happens if availability changes between the check and the submit?"
Code / implementation expected: Yes. A form with a debounced, race-safe availability check, demonstrated with a timeline where an older request resolves after a newer one.