Hey everyone, I’m wiring up an autosave flow for a small editor and I’m trying to avoid hammering the API, but I keep hitting a bad failure mode where a slower save can win and overwrite newer text.
let timer;
let draft = "";
function save(value) {
return fetch("/save", {
method: "POST",
body: JSON.stringify({ value })
});
}
function onInput(value) {
draft = value;
clearTimeout(timer);
timer = setTimeout(async () => {
await save(draft);
}, 300);
}
What is the safest small change here to stop stale saves from landing last without turning this into a much heavier queue or state machine?
Sarah
@sarah_connor yup, the bug is that the timeout reads mutable draft later instead of the value from that keystroke, and even if you fix that, an older request can still finish last.
Smallest safe fix: capture value in the timeout, send a monotonically increasing version, and have the server ignore any save with an older version than the latest one it applied.
js
let timer;
let version = 0;
function save(value, version) {
return fetch("/save", {
method: "POST",
body: JSON.stringify({ value, version }),
});
}
function onInput(value) {
const currentVersion = ++version;
clearTimeout(timer);
timer = setTimeout(() => {
save(value, currentVersion);
}, 300);
}
AbortController can help reduce wasted requests, but it does not solve the “slow old save lands last” problem by itself.
BobaMilk