Created
January 14, 2017 11:54
-
-
Save fracz/972ff3abdaf00b2b6dd94888df0a393b to your computer and use it in GitHub Desktop.
Typescript memoize decorator with expiration time
This file contains 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
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); | |
}); | |
}); |
This file contains 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
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
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.