2015-07-15 12:30:11 +08:00
|
|
|
/**
|
|
|
|
* The `computed` utility creates a function that will cache its output until
|
|
|
|
* any of the dependent values are dirty.
|
|
|
|
*
|
|
|
|
* @param {...String} dependentKeys The keys of the dependent values.
|
|
|
|
* @param {function} compute The function which computes the value using the
|
|
|
|
* dependent values.
|
2015-08-26 15:41:54 +08:00
|
|
|
* @return {Function}
|
2015-07-15 12:30:11 +08:00
|
|
|
*/
|
|
|
|
export default function computed(...dependentKeys) {
|
|
|
|
const keys = dependentKeys.slice(0, -1);
|
|
|
|
const compute = dependentKeys.slice(-1)[0];
|
|
|
|
|
|
|
|
const dependentValues = {};
|
|
|
|
let computedValue;
|
2015-04-25 20:58:39 +08:00
|
|
|
|
|
|
|
return function() {
|
2015-07-15 12:30:11 +08:00
|
|
|
let recompute = false;
|
|
|
|
|
|
|
|
// Read all of the dependent values. If any of them have changed since last
|
|
|
|
// time, then we'll want to recompute our output.
|
|
|
|
keys.forEach(key => {
|
|
|
|
const value = typeof this[key] === 'function' ? this[key]() : this[key];
|
|
|
|
|
|
|
|
if (dependentValues[key] !== value) {
|
2015-04-25 20:58:39 +08:00
|
|
|
recompute = true;
|
2015-07-15 12:30:11 +08:00
|
|
|
dependentValues[key] = value;
|
2015-04-25 20:58:39 +08:00
|
|
|
}
|
2015-07-15 12:30:11 +08:00
|
|
|
});
|
|
|
|
|
2015-04-25 20:58:39 +08:00
|
|
|
if (recompute) {
|
2015-07-15 12:30:11 +08:00
|
|
|
computedValue = compute.apply(this, keys.map(key => dependentValues[key]));
|
2015-04-25 20:58:39 +08:00
|
|
|
}
|
2015-07-15 12:30:11 +08:00
|
|
|
|
|
|
|
return computedValue;
|
|
|
|
};
|
|
|
|
}
|