如何解决NodeJS在单例类中使用装饰器不会在初始化后保存类的状态
我有一个MongoQueryResolver
类,其中包含一个字典:
private queries: {[key: string]: (params) => any} = {};
此词典通过键保存函数,其中每个函数都是MongoDB的查询函数。
我创建了一个装饰器MongoQuery
,它代表一个mongo查询函数:
export function MongoQuery(queryName: string) {
return function decorator(target,key,func) {
target.register(queryName,func);
}
}
此修饰器调用MongoQueryResolver#register
以便在字典中注册查询,因此我可以按查询名称使用它。
我创建的MongoQuery函数示例:
@MongoQuery(QueryType.GET_ALL_ENABLED)
public async getAllEnabled(params) {
const workersDb = MongoService.getBranch(Branches.WORKERS).db("workers");
const configCollection = await workersDb.collection('config');
const criteria: any = {isEnabled: true};
if (params.proxy) {
criteria.proxy = params.proxy;
}
return await configCollection.find(criteria).toArray();
}
以及我在户外如何使用它:
MyRoutes.get('/get-enabled',async (req,res) => {
const data = await MongoQueryResolver.resolve(QueryType.GET_ALL_ENABLED,{proxy: req.query.proxy});
res.json(data);
});
问题
当我的应用程序启动时,我在字典上打印字典:
set GET_ALL_ENABLED {
value: [Function: getAllEnabled],writable: true,enumerable: false,configurable: true
}
{
GET_ALL_ENABLED: {
value: [Function: getAllEnabled],configurable: true
}
}
但是当我开始使用字典时,它是空的..
我用export default new MongoQueryResolver()
将班级标记为单身人士
为什么会发生?似乎好像是一个新实例?
import MongoQueryResolver from '../../services/mongo/mongo-query-resolver'
解决方法
调试一段时间后,我发现了问题所在。
发生这种情况有一个原因,我希望我是对的。
在开始之前,让我展示一个小的简化示例:
装饰器
export function MongoQuery(queryName: string) {
return function decorator(target: any,key: any,func: any) {
target.register(queryName,func);
}
}
解析器单例
class Resolver {
map: any;
constructor() {
this.map = {};
}
register(queryName: any,func: any) {
this.map[queryName] = func;
}
resolve(queryName: string) {
this.map[queryName]();
}
@MongoQuery('myQuery')
public testQuery() {
console.log("test!");
}
}
export default new Resolver();
index.ts
Resolver.resolve("myQuery");
此示例与我的原始示例非常相关的问题是,当装饰器在类创建时运行时,它不运行构造函数,也不初始化类变量(如果您执行{{1} })
这意味着map = {}
仅在装饰器运行之后设置。
要解决此问题,我将必须检查寄存器功能是否存在map
,否则,只需对其进行设置。
this.map
现在,我将始终设置register(queryName: any,func: any) {
this.map = this.map || {};
this.map[queryName] = func;
}
属性。
现在剩下的唯一问题是map
函数,当您将函数保存在字典中时,它看起来像这样:
resolve
这就是为什么我得到 {
value: [Function: testQuery],writable: true,enumerable: false,configurable: true
}
的原因,所以我必须运行is not a function
而不是this.map[queryName]()
来运行函数。
希望这对任何人都有帮助!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。