Skip to content

Instantly share code, notes, and snippets.

@siandreev
Last active October 20, 2021 11:46
Show Gist options
  • Save siandreev/856612ccc8ae308072974353facc4f1b to your computer and use it in GitHub Desktop.
Save siandreev/856612ccc8ae308072974353facc4f1b to your computer and use it in GitHub Desktop.
Caching decorator example
class Calculator {
@Cache(200)
public add(a: number, b: number): number {
console.log('add called!')
return a + b;
}
@Cache(3000)
public sub(a: number, b: number): number {
console.log('sub called!')
return a - b;
}
}
const hash = (args: unknown[]) => args.join(',');
// вызывается один раз для каждого метода при инициализации методов класса
// (при создании массива в __decorate)
function Cache(storeTime) {
const store = new Map<string, { timestamp: number, value: unknown }>();
// вызывается один раз для каждого метода при инициализации методов класса
// внутри цикла в __decorate
return function(
target: Object,
propertyKey: string | symbol,
descriptor: TypedPropertyDescriptor<any>
): TypedPropertyDescriptor<any> | void {
const originalMethod = descriptor.value;
console.log('Decorator called for', propertyKey);
// вызывается каждый раз при вызове метода
descriptor.value = function(...args) {
const key = hash(args);
if (store.has(key)) {
const { timestamp, value } = store.get(key);
if (timestamp + storeTime > Date.now()) {
return value;
}
}
const value = originalMethod.apply(this, args);
store.set(key, { timestamp: Date.now(), value });
return value;
}
}
}
const calc = new Calculator();
console.log(calc.add(1, 2));
console.log(calc.sub(2, 1));
console.log(calc.add(1, 3));
console.log(calc.sub(3, 1));
setTimeout(() => {
console.log('SetTimeout callback');
console.log(calc.add(1, 2));
console.log(calc.sub(2, 1));
}, 400)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment