Last active
May 29, 2019 08:22
-
-
Save mikeapr4/88d4eb7f42df7b6de876c135d1f705d3 to your computer and use it in GitHub Desktop.
example of reactive method-style getter caching
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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