Javascript NodeJ要求类返回{}
因此,我正在创建一个单例类,当我从我的Javascript NodeJ要求类返回{},javascript,node.js,es6-modules,Javascript,Node.js,Es6 Modules,因此,我正在创建一个单例类,当我从我的server.js文件中需要它时,它可以正常工作,但当我从另一个文件中需要它时,它返回为未定义。我会尝试发布相关代码,但有些代码会因为工作而被删掉 server.js const createServices = require('./factories/services.js'); const injector = require('./lib/injector'); const Injector = new injector(); const serv
server.js
文件中需要它时,它可以正常工作,但当我从另一个文件中需要它时,它返回为未定义。我会尝试发布相关代码,但有些代码会因为工作而被删掉
server.js
const createServices = require('./factories/services.js');
const injector = require('./lib/injector');
const Injector = new injector();
const services = createServices(Injector, [require('./server/amq_listeners/fb_configs.listener'), require('./server/models/FBConfigs')]);
services.forEach((service, name) => {
Injector.register(name, service);
});
// Start services
Injector.start();
const express=require('express');
const bodyParser=require('body-parser');
const path=require('path');
const http=require('http');
常量app=express();
const config=require('config');
const FBConfigsListener=require('./server/amq_listeners/fb_configs.listener');
const FBConfigs=require('./server/models/FBConfigs');
//用于与mongodb交互的Api文件
const api=require('./server/routes/api.routes');
//解析器
use(bodyParser.json());
use(bodyParser.urlencoded({extended:false}));
//角度距离输出文件夹
使用(express.static(path.join(uu dirname,'dist'));
//Api位置
应用程序使用('/api',api);
//将所有其他请求发送到angular
应用程序获取(“*”,(请求,请求)=>{
res.sendFile(path.join(uu dirname,'dist/index.html');
});
//设置端口
var port=config.get('webserver.port');
应用程序集(“端口”,端口);
const server=http.createServer(app);
server.listen(端口,()=>console.log(`Running on localhost:${port}`))代码>它是由循环依赖项引起的。你应该避免使用或非常小心
在您的情况下,修复可能非常简单,移动行var FBConfigs=require('../models/FBConfigs')代码>来自侦听器,位于文件末尾,作为最后一行(是,即使在module.exports之后)
编辑:事实上,这可能是不够的,因为我更详细地检查了代码。由于您没有在FBConfig构造函数中使用侦听器,您可以创建方法assignListener
,从该构造函数中删除this.Listener
,然后在server.js
中调用它,该方法将执行this.Listener
或者是最后一个解决方案,也是“最佳实践”。不要导出实例。仅导出类。然后在server.js中,在需要这两个实例之后创建这些实例。我建议您首先实例化依赖项,并将它们存储在某个对象中,然后将其传递给依赖类。结构可以是
工厂/服务.js
/*
* Instantiates passed services and passes injector object to them
*/
module.exports = function createServices(injector, services) {
return Object.entries(services)
.reduce((aggregator, [name, serv]) => {
const name_ = camelCase(name);
aggregator.set(name_, new serv(injector));
return aggregator;
}, new Map());
};
lib/service.js
/**
* Base class for classes need any injections
*/
module.exports = class Service {
constructor(injector) {
this.injector = injector;
}
get dependencies() {
return this.injector.dependencies;
}
/*
* Background jobs can be ran here
*/
async startService() {}
/*
* Background jobs can be stopped here
*/
async stopService() {}
};
lib/injector.js
const Service = require('./service');
/*
* Contains all dependencies
*/
module.exports = class Injector {
constructor() {
this.services = new Map();
this._dependencies = {};
}
has(name) {
return this.services.has(name);
}
register(name, service) {
if (this.has(name)) {
throw new Error(`Service ${name} already exists`);
}
if (service instanceof Service === false) {
throw new Error('Argument #2 should be an instance of Service');
}
this.services.set(name, service);
this._dependencies[name] = service;
}
unregister(name) {
if (! this.has(name)) {
throw new Error(`Service ${name} not found`);
}
this.services.delete(name);
delete this._dependencies[name];
}
get dependencies() {
return { ...this._dependencies };
}
/*
* Starts all registered services
*/
async start() {
for (let service of this.services.values()) {
await service.startService();
}
}
/*
* Stops all registered services
*/
async stop() {
for (let service of this.services.values()) {
await service.stopService();
}
}
};
然后在主文件中导入、初始化和绑定服务(不要忘记只导出一个类,而不是像现在这样导出一个对象)
server.js
const createServices = require('./factories/services.js');
const injector = require('./lib/injector');
const Injector = new injector();
const services = createServices(Injector, [require('./server/amq_listeners/fb_configs.listener'), require('./server/models/FBConfigs')]);
services.forEach((service, name) => {
Injector.register(name, service);
});
// Start services
Injector.start();
将所需的类继承到服务
类,您将可以访问那里的所有依赖项(不要忘记从构造函数调用super()
)。像
模型/FBConfigs.js
const Service = require('../lib/service');
class FBConfigs extends Service {
constructor(injector) {
super(injector);
const { FBConfigsListener } = this.dependencies;
...your code here
}
async startService() {
...run bg job or init some connection
}
async stopService() {
...stop bg job or close some connection
}
}
module.exports = FBConfigs;
您还可以将一些配置对象传递给createServices
(我在这里没有包含它),键等于包含配置对象的服务名称和值,并将配置传递给相应的服务。非常感谢。我要试一试@如果这个答案解决了你的问题,那么你可以考虑接受它作为正确的答案。没有问题。如果你需要一些澄清,请告诉我。如果我想让这个类成为一个单身学生,我该怎么办?这仍然有效吗?我不想继续创建新实例或FBConfigs或FBConfigsListener,因为它们在后台运行,从活动mq收集数据。这个解决方案是这样工作的吗?我想做我现在正在做的导出对象的事情吗?所有类在createServices
函数中只初始化一次,它们的实例将存储在一个Injector
对象中。只要您通过Injector
实例访问它们,它们就会指向相同的服务
实例。我将用启动/停止服务的可能性来补充答案。我只导出了该对象,因为我试图创建一个单例。但是我确实将require移到了module.exports下面,它开始工作了。但我会尝试上面贴的东西,这样我就可以遵循最佳实践。