javascript - 作用域方法装饰器到一个类的实例
问题描述
我正在尝试使用方法装饰器构建一个简单的缓存。
假设我有以下课程:
class Contract {
constructor(public readonly contractAddress: string) {}
@cache()
async getBalance(): Promise<number> {
// Get balance for this.contractAddress from a backend and return it
return balance
}
}
我目前有以下缓存装饰器:
const promiseCache = new Map<string, Promise<unknown>>()
const cache = () => {
return (_target: Object, propertyKey: string, descriptor: PropertyDescriptor) => {
const originalMethod = descriptor.value
descriptor.value = async function (...args: any[]) {
const constructedKey = constructKey(args)
const promise = promiseCache.get(constructedKey)
if (promise) {
return promise
} else {
const newPromise = originalMethod.apply(this, args)
promiseCache.set(constructedKey, newPromise)
return newPromise
}
}
return descriptor
}
}
如果我只有这个类的一个实例,这很好用。但是,如果我创建一个不同的第二个实例contractAddress
,那么缓存似乎是相同的。
// Example
const a = new Contract('a') // has balance of 1
const b = new Contract('b') // has balance of 2
await a.getBalance() // returns 1
await b.getBalance() // returns 1
我试图找到这个问题的答案,但我发现的唯一一件事是无法将类的实例传递给装饰器,因此我无法访问contractAddress
以将其添加到我的密钥中。
我还尝试将“promiseCache”放入装饰器工厂,但这也不起作用。
我尝试的最后一件事是向装饰器工厂添加一个参数,但这也没有用。
// THIS DOES NOT WORK
const cache = (id: number) => { ... }
@cache(Math.random())
getBalance() { ... }
// This gave me a random number in the decorator, but it seemed to be the same one per method across all instances
// or
@cache(this.contractAddress) // This doesn't even compile
getBalance() { ... }
这可能吗?我看到的唯一两个解决方案是不使用装饰器并在每个方法中添加缓存(由于额外的样板,我想避免这种情况),或者将 contractAddress 作为每个方法的参数传递,这也不是很好.
解决方案
推荐阅读
- swift - Stackview不在界面生成器中显示高度不确定的项目
- json - 类型脚本中要加载到对象中的复杂 JSON 类型
- php - 如何在PHP中上传本地文件夹中的文件并同时将其添加到数据库中?
- ios - Xcode 10.2 无法在 iOS < 10 的模拟器上运行应用程序
- python - mask-rcnn 无法正确屏蔽“细长”对象,例如动物尾巴
- php - 在线测验 问题 ID 未插入数据库
- node.js - 本地主机没有发送任何数据 - ERR_EMPTY_RESPONSE
- google-sheets - 在 Google 工作表中查找相似值并移动单元格
- java - 类仍然通过 PHP 中的旧数组
- mule - 在 Mule 4 中声明动态数据编织变量,就像我们在 Mule 3 中所做的那样