使用express.js的es6类,如何传递类的实例以便每个路由都可以访问?

时间:2018-01-24 19:41:18

标签: 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);
  }
}

让我说我运行我的应用程序并发生一些事件。然后我调用manager.addEntity(...some_event...);

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;

2 个答案:

答案 0 :(得分:1)

单例类是否合理是根据具体情况决定的。

如果使用某个类可以提供某些好处,那么这是合理的:

如果有可能需要多次实例化(嵌套应用程序,测试等),它可以是具有默认实例的类。这自然由JS模块提供,包括ES模块:

export class Manager {
  constructor() {
    this.table = [];
  }
  addEntity(obj) {
    this.table.push(obj);
  }
}

export default new Manager();

请注意,如果需要实例化或扩展Manager,则会导出export default { table: [], addEntity(obj) { this.table.push(obj); } };

如果不是这种情况,那么可以应用KISS原则,而可以使用普通对象:"

addEntity

KISS原则可以进一步应用;如果将一个对象推送到数组是该类所做的全部,app.set('managed entities', []); ... app.get('managed entities').push(...); 并非如此。它可以省略,所以我们最终得到一个数组。

在Express.js中,应用程序范围的变量通常存储为application settings,因此可以从应用程序实例存储和检索变量(整个对象或表数组):

managed entities

要求是访问应用程序实例,因此使用MyApp-Swift设置的代码应驻留在中间件函数中。另一方面,这提供了更大的灵活性。如果需要,可以覆盖该设置。

答案 1 :(得分:0)

编辑:请参阅下面Bergi的评论,了解为什么我发布的答案是个坏主意。

-

导出所有路由导入的该类的实例。可能是这样的(单实例模式):

class Manager {
    ...
}

export default new Manager();