Javascript 使用express.js的es6类,如何传递类的实例以便每个路由都可以访问?
我定义了一个类来跟踪一些动态数据,这些数据将在运行时更新。我希望该类的实例可由我在应用程序中定义的所有路由访问:Javascript 使用express.js的es6类,如何传递类的实例以便每个路由都可以访问?,javascript,node.js,express,ecmascript-6,Javascript,Node.js,Express,Ecmascript 6,我定义了一个类来跟踪一些动态数据,这些数据将在运行时更新。我希望该类的实例可由我在应用程序中定义的所有路由访问: export default class Manager { constructor() { let self = this; self.table = []; } addEntity(obj){ let self = this; self.table.push(obj); } } 假设我运行我的应用程序时发生了一些事件。然后调用ma
export default class Manager {
constructor() {
let self = this;
self.table = [];
}
addEntity(obj){
let self = this;
self.table.push(obj);
}
}
假设我运行我的应用程序时发生了一些事件。然后调用manager.addEntity(…一些事件…)代码>
self.table
将有一个新元素。我希望能够让路由通过请求路由的url来访问此信息,可能是GET/api/table/
。不幸的是,我目前无法访问该类的实例
我应该将类实例的引用分配给全局变量吗?这是一种反模式,如果可能的话,我希望避免这样做
我的服务器是使用普通推荐代码定义的:
import http from 'http';
import { env, mongo, port, ip, apiRoot } from './config';
import api from './api';
import express from './services/express';
import mongoose from './services/mongoose';
import Manager from './lib/manager.js';
const app = express(apiRoot, api);
const server = http.createServer(app);
mongoose.connect(mongo.uri, { useMongoClient: true });
mongoose.Promise = Promise;
new Manager().initialize(server);
setImmediate(() => {
server.listen(port, ip, () => {
console.log(
'Express server listening on http://%s:%d, in %s mode',
ip,
port,
env,
);
});
});
export default app;
编辑:请参考下面Bergi的评论,了解为什么我发布的答案是个坏主意。
--
导出所有路由导入的该类的实例。相反,可能类似于以下内容(单实例模式):
编辑:请参考下面Bergi的评论,了解为什么我发布的答案是个坏主意。
--
导出所有路由导入的该类的实例。相反,可能类似于以下内容(单实例模式):
单例类是否合理取决于具体情况
如果使用一个类可以提供某些好处,那么它是合理的:
- 一个类可以多次实例化,但应该存在默认实例
- 一个类可以扩展
- 类可以提供语法或功能上的好处(例如)
如果有可能需要多次实例化(嵌套应用程序、测试等),那么它可以是具有默认实例的类。这自然是由JS模块提供的,包括ES模块:
export class Manager {
constructor() {
this.table = [];
}
addEntity(obj) {
this.table.push(obj);
}
}
export default new Manager();
请注意,Manager
是在需要实例化或扩展时导出的
如果不是这样,则可以应用KISS原则,而可以使用plain object:
KISS原理可以进一步应用;如果类只需将对象推送到数组中,addEntity
没有多大帮助。它可以省略,因此我们最终得到一个数组
在Express.js中,应用程序范围内的变量通常存储为,因此可以从应用程序实例存储和检索变量(整个对象或表数组):
app.set('managed entities', []);
...
app.get('managed entities').push(...);
要求是能够访问应用程序实例,因此使用托管实体设置的代码应该驻留在中间件功能内部。另一方面,这提供了更大的灵活性。如果需要,可以覆盖该设置。单例类是否合理取决于具体情况
如果使用一个类可以提供某些好处,那么它是合理的:
- 一个类可以多次实例化,但应该存在默认实例
- 一个类可以扩展
- 类可以提供语法或功能上的好处(例如)
如果有可能需要多次实例化(嵌套应用程序、测试等),它可以是一个具有默认实例的类。这自然是由JS模块提供的,包括ES模块:
export class Manager {
constructor() {
this.table = [];
}
addEntity(obj) {
this.table.push(obj);
}
}
export default new Manager();
请注意,Manager
是在需要实例化或扩展时导出的
如果不是这样,则可以应用KISS原则,而可以使用plain object:
接吻原则可以进一步应用;如果类只需将对象推送到数组中,addEntity
没有多大帮助。它可以省略,因此我们最终得到一个数组
在Express.js中,应用程序范围内的变量通常存储为,因此可以从应用程序实例存储和检索变量(整个对象或表数组):
app.set('managed entities', []);
...
app.get('managed entities').push(...);
要求是能够访问应用程序实例,因此使用托管实体设置的代码应该驻留在中间件功能中。另一方面,这提供了更多的灵活性。如果需要,可以覆盖该设置。这会不会为导入它的每个路由创建一个新实例?嗯,根据这一点:--如果只对工作模块求值一次,这将确保只创建/使用一个实例!如果您想要单例,不要使用类
。在@Bergi的链接中使用函数单例是有效的。我们将引用导出到对象,因此在导入时始终使用相同的对象。谢谢。这不会为导入它的每个路由创建一个新实例吗?嗯,根据这个:--应该只对工作模块求值一次,这确保只创建/使用一个实例!如果您想要单例,不要使用类
。在@Bergi的链接中使用函数单例是有效的。我们将引用导出到对象,因此在导入时始终使用相同的对象。谢谢。听起来你确实在寻找一个全局变量。整个应用程序中只有一个类实例?听起来您确实在寻找一个全局变量。整个应用程序中只有一个类实例?