NodeJS 在单例 class 中使用装饰器不会在初始化后保存 class 的状态
NodeJS Using decorators with a singleton class does not save the state of the class after init
我有一个 class 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],
writable: true,
enumerable: false,
configurable: true
}
}
但是当我开始使用字典时,它是空的..
我通过 export default new MongoQueryResolver()
将 class 标记为单例
为什么会这样?好像是新实例?
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");
这个例子的问题与我原来的例子非常相关,当装饰器 运行s 在 class 创建时, 它不会 运行 构造函数,也不初始化 class 变量(如果你在顶部做 map = {}
)
这意味着map
只会在装饰器运行s之后设置。
为了解决这个问题,如果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].value()
到 运行 函数而不是 this.map[queryName]()
。
希望这对任何人都有帮助!
我有一个 class 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],
writable: true,
enumerable: false,
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");
这个例子的问题与我原来的例子非常相关,当装饰器 运行s 在 class 创建时, 它不会 运行 构造函数,也不初始化 class 变量(如果你在顶部做 map = {}
)
这意味着map
只会在装饰器运行s之后设置。
为了解决这个问题,如果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].value()
到 运行 函数而不是 this.map[queryName]()
。
希望这对任何人都有帮助!