Skip to content

Instantly share code, notes, and snippets.

@mikeapr4
Last active May 29, 2019 08:22
Show Gist options
  • Save mikeapr4/88d4eb7f42df7b6de876c135d1f705d3 to your computer and use it in GitHub Desktop.
Save mikeapr4/88d4eb7f42df7b6de876c135d1f705d3 to your computer and use it in GitHub Desktop.
example of reactive method-style getter caching
// recreation of a computed property
const computed = (vm, func) => {
vm.$watch(
func,
null, // callback not used for lazy
{ lazy: true }, // lazy means we can just flag as dirty
);
// eslint-disable-next-line no-underscore-dangle
const watcher = vm._watchers[vm._watchers.length - 1];
// add an accessor
watcher.lazyValue = () => {
if (watcher.dirty) {
watcher.evaluate();
}
watcher.depend(); // means any calling computed will have transitive deps
return watcher.value;
};
return watcher;
};
// Cache Wrapper for Method-style Getter
const methodStyleCache = (getVM, getter) => {
let watchers = {};
return (...args) => {
// Remove old watchers if the getter is rebuilt
Object.values(watchers).forEach((w) => w.teardown());
watchers = {};
const innerMethod = getter.call(null, ...args);
return (id) => {
let watcher = watchers[id];
if (!watcher) {
watcher = computed(getVM(), () => innerMethod(id));
watchers[id] = watcher;
}
return watcher.lazyValue();
};
};
};
// Cacher that can be attached as a plugin to get a store reference
const methodGetterCacher = () => {
let store;
const getVM = () => store._vm;
return {
plugin: (st) => { store = st; },
cache: (getter) => methodStyleCache(getVM, getter),
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment