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]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
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.