mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Docs: trim arch 05 debounced-renderer sketch to its generation-guard insight
This commit is contained in:
@@ -384,49 +384,23 @@ export interface DebouncedRenderer {
|
|||||||
cancel(): void;
|
cancel(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createDebouncedRenderer(opts: {
|
// The factory wires the three operations over one timer. schedule() does
|
||||||
/** Current debounce delay in ms; read fresh each schedule so settings apply live. */
|
// `setTimeout(run, delayMs())`, clearing any pending timer first (delayMs read fresh
|
||||||
delayMs: () => number;
|
// so a settings change applies live); flush() clears the timer and runs now; cancel()
|
||||||
/** Performs one render. Reads the current spec/theme; awaits the embed. */
|
// clears it and bumps `generation`. The non-obvious part is out-of-order protection:
|
||||||
render: () => Promise<void>;
|
function createDebouncedRenderer(opts): DebouncedRenderer {
|
||||||
/** Toggle the non-blocking busy indicator. */
|
let generation = 0;
|
||||||
setBusy: (busy: boolean) => void;
|
|
||||||
}): DebouncedRenderer {
|
|
||||||
let timer: ReturnType<typeof setTimeout> | null = null;
|
|
||||||
let generation = 0; // guards against a stale in-flight render finishing late
|
|
||||||
|
|
||||||
const run = async () => {
|
const run = async () => {
|
||||||
timer = null;
|
const mine = ++generation; // capture this render's turn
|
||||||
const mine = ++generation;
|
|
||||||
opts.setBusy(true);
|
opts.setBusy(true);
|
||||||
try {
|
try {
|
||||||
await opts.render();
|
await opts.render();
|
||||||
} finally {
|
} finally {
|
||||||
// Only the most recent render clears the indicator.
|
if (mine === generation) opts.setBusy(false); // only the latest render clears it
|
||||||
if (mine === generation) opts.setBusy(false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// …schedule/flush/cancel as above. A slow render that resolves after a newer one
|
||||||
return {
|
// fails the `mine === generation` check, so it can't clobber the fresh view/indicator.
|
||||||
schedule() {
|
|
||||||
if (timer) clearTimeout(timer); // cancel the pending render
|
|
||||||
timer = setTimeout(run, opts.delayMs());
|
|
||||||
},
|
|
||||||
flush() {
|
|
||||||
if (timer) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
timer = null;
|
|
||||||
}
|
|
||||||
void run();
|
|
||||||
},
|
|
||||||
cancel() {
|
|
||||||
if (timer) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
timer = null;
|
|
||||||
}
|
|
||||||
generation++; // abandon any in-flight result
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user