Skip to content

Instantly share code, notes, and snippets.

@fracz
Created January 14, 2017 11:54
Show Gist options
  • Save fracz/972ff3abdaf00b2b6dd94888df0a393b to your computer and use it in GitHub Desktop.
Save fracz/972ff3abdaf00b2b6dd94888df0a393b to your computer and use it in GitHub Desktop.
Typescript memoize decorator with expiration time
import {memoize, clearMemoizedValue} from "./memoize";
describe("memoize", () => {
class MyClass {
@memoize(5)
getNumber() {
return Math.random();
}
}
let a: MyClass;
beforeEach(() => {
a = new MyClass;
});
it("memoizes the value", () => {
expect(a.getNumber()).toEqual(a.getNumber());
});
it("allows to manually clear the value", () => {
let first = a.getNumber();
clearMemoizedValue(a.getNumber);
expect(a.getNumber).not.toEqual(first);
});
it("clears the value automatically after timeout", (done) => {
let first = a.getNumber();
setTimeout(() => {
expect(a.getNumber).not.toEqual(first);
done();
}, 6);
});
});
const MEMOIZED_VALUE_KEY = '_memoizedValue';
export function memoize(expirationTimeMs: number = 60000) {
return (target: any, propertyName: string, descriptor: TypedPropertyDescriptor<any>) => {
if (descriptor.value != null) {
const originalMethod = descriptor.value;
let fn = function (...args: any[]) {
if (!fn[MEMOIZED_VALUE_KEY]) {
fn[MEMOIZED_VALUE_KEY] = originalMethod.apply(this, args);
setTimeout(() => clearMemoizedValue(fn), expirationTimeMs);
}
return fn[MEMOIZED_VALUE_KEY];
};
descriptor.value = fn;
return descriptor;
}
else {
throw "Only put the @memoize decorator on a method.";
}
}
}
export function clearMemoizedValue(method) {
delete method[MEMOIZED_VALUE_KEY];
}
@fracz
Copy link
Author

fracz commented Jan 14, 2017

Idea based on the memoize-decorator.ts by @dsherret. Can be perfectly used with promises and API requests.

It stores the memoized value as the method attribute (the original stores the value in the object that owns the method).

It allows to clear the memoized value manually when it needs to be recalculated (clearMemoizedValue(someService.someAnnotatedMethod)). It also clears the value automatically after the specified time so the next call will recalculate it.

The following code with memoize (cache) the returned value for 5 seconds.

@memoize(5000)
findAllEntities() { ... }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment