実行すると計算結果をキャッシュするデコレータがあると便利です
下記のようにかけるようになります
import { memoized } from '~/util/memoizedMethod'
class Foo {
@memoized
async action() {
console.log('₍₍(ง˘ω˘)ว⁾⁾')
}
@memoized
get magicNumber() {
console.log('42')
return 42
}
}
const foo = new Foo()
foo.magicNumber // 42
foo.magicNumber // なにも出ない
foo.magicNumber // なにも出ない
await foo.action() // ₍₍(ง˘ω˘)ว⁾⁾
await foo.action() // なにも出ない
await foo.action() // なにも出ない
実装
const memoized = (_target: any, _propKey: string, descriptor: PropertyDescriptor) => {
const key =
'function' === typeof descriptor.value ? 'value' :
'function' === typeof descriptor.get ? 'get' :
null
if (!key) return
const original = descriptor[key]
const map = new WeakMap<any, { v: any }>()
descriptor[key] = function() {
const r = map.get(this)
if (r) return r.v
const v = Reflect.apply(original, this, arguments)
map.set(this, { v })
return v
}
if ('get' === key && 'function' === typeof descriptor.set) {
const original = descriptor.set
descriptor.set = function() {
Reflect.apply(original, this, arguments)
map.delete(this)
}
}
}
引数を持つメソッドなどに使うとうまく動かないので型エラーが出るようにしたいけど無理っぽい?