Debounced computeds
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1.2k
- Forks
- 130
- PR merge metrics
- No merged PRs in 30d
Description
I've been playing with debouncing computeds. I have a complex & CPU-expensive computed that subscribes to many observables, and I'd to debounce recalculations there.
I haven't been able to find a nice way to do this. #24 gets close, but was never merged, and only works for debouncing downstream updates, not debouncing incoming updates, so isn't really sufficient (unless your computed has only one or two inputs).
I know this breaks the general contract of @computed, fully agree this shouldn't be a common case, but I do think it's a useful niche case. I've got the below currently working as drop-in alternative for @computed decorators, which I think works nicely.
A) Is there anything obviously wrong with this approach, or any other existing alternatives I've missed?
B) If not, would you be interested in including it in mobx-utils?
function debounceComputed<T>(timeoutMs: number, computedOptions: IComputedValueOptions<T> = {}) {
return <T>(target: any, key: string, descriptor: PropertyDescriptor): void => {
if (!descriptor.get) throw new Error('debounceComputed requires a getter');
const internalFn = descriptor.get as () => T;
let cachedValue: { value: T, atom: IAtom } | undefined;
return computed(computedOptions)(target, key, { ...descriptor, get: function () {
if (cachedValue) {
// Don't calculate until the atom pings us
cachedValue.atom.reportObserved();
} else {
// Calculate and cache the result:
cachedValue = { value: internalFn.apply(this), atom: createAtom("DebounceAtom") };
// Batch subsequent runs for the next timeoutMs:
setTimeout(() => {
const { atom } = cachedValue!;
cachedValue = undefined;
atom.reportChanged(); // Ping subscribers to update
}, timeoutMs);
}
return cachedValue.value;
}});
};
}
I'm still using mobx 5, but as far as I'm aware the same concept (same code?) should work just the same in v6.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No repository files or tests are named. Start by reviewing the proposed debounceComputed decorator and the MobX 5 and 6 computed/createAtom behavior it relies on; done would require agreement on the API and semantics, followed by an accepted implementation and tests for debounced incoming updates.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100