NodeJS Express中每个请求的全局范围

我有一个基本的快递服务器,需要在每个请求处理期间存储一些全局variables。 更深入地说,请求处理涉及许多操作,需要存储在一个variables中,如global.transaction[]

当然,如果我使用global范围,每个连接将共享其事务的信息,我需要一个全局范围,因为我需要在执行期间从许多其他模块访问事务数组。

有关这个问题的任何build议? 我觉得是非常微不足道的,但我正在寻找复杂的解决scheme:)

非常感谢!

更新这是一个案例情况,更清楚。

每个请求我有3个模块( ModuleAModuleBModuleC ),它读取一个目录中的10个随机文件的内容。 我想跟踪每个请求读取的文件名列表,并发送res.write列表。

因此, ModuleA/B/C需要访问一个全局variables,但request_1request_2request_3等列表不必混淆。

       

网上收集的解决方案 "NodeJS Express中每个请求的全局范围"

这是我的build议避免像火灾一样的全球状态

  • 从我的经验来看,这是Node服务器中的头号维护问题。
  • 它使您的代码不可组合,更难以重用。
  • 它会在你的代码中创build隐含的依赖关系 – 你永远不能确定哪个部分取决于哪个部分,而且不容易validation。

您希望应用程序使用的代码部分尽可能的明确 。 这是一个很大的问题。

问题

我们希望跨多个请求同步状态并采取相应的行动。 这是编写软件时遇到的一个非常大的问题 – 有人甚至说是最大的问题。 对象在应用程序交stream中的重要性不能被高估。

一些解决scheme

有几种方法可以在Node服务器上跨越请求或服务器范围完成共享状态。 这取决于你想要做什么。 这是两个最常见的imo。

  1. 我想观察请求的作用。
  2. 我想要一个基于另一个请求做什么的请求。

我想观察请求的作用

再次,有很多方法可以做到这一点。 这是我最看重的两个。

使用事件发射器

这样请求发出事件。 应用程序读取请求触发的事件并相应地了解它们。 应用程序本身可以是一个可以从外部观察的事件发射器。

你可以做一些事情:

 request.emit("Client did something silly",theSillyThing)l 

然后, 如果你select从外面听。

使用观察者模式

这就像一个事件发射器,但倒过来。 当请求发生一些有趣的事情时,你可以保存一个请求的依赖列表,并自己调用一个处理方法。

就我个人而言,我通常更喜欢事件发射器,因为我认为他们通常更好地解决事件。

2.我想要一个基于另一个请求做什么的请求。

这比听音乐更有效。 再次,这里有几种方法。 他们的共同点是我们把分享放在一个服务中

而不是具有全局状态 – 每个请求都可以访问服务 – 例如,当您读取通知服务的文件以及何时需要读取文件列表时,您可以询问服务。 一切都在依赖中明确。

该服务不是全球性的,只是它的依赖。 例如,它可以协调资源和数据,是Repository的某种forms)。

好理论! 那我的用例呢?

这里有两个选项, 会做你的情况。 这远非唯一的解决scheme。

第一个选项:

  • 每个模块都是一个事件发射器,每当他们读取一个文件,他们发出一个事件。
  • 服务监听所有的事件,并保持计数。
  • 请求可以显式访问该服务,并可以查询它以获取文件列表。
  • 请求通过模块本身进行写入,而不是添加的服务。

第二个选项:

  • 创build一个拥有module1,module2和module3副本的服务。 (组成)
  • 该服务根据需要将操作委托给模块。
  • 该服务保留了由于请求通过它而被访问的文件列表。
  • 请求直接停止使用模块 – 而是使用服务。

这两种方法都有优点和缺点。 可能需要一个更复杂的解决scheme(这两个实际上很简单),但是我认为这是一个好的开始。

一个简单的方法是将数据存储在请求对象上。

这里是一个例子(使用Express):

 app.get('/hello.txt', function(req, res){ req.transaction = req.transaction || []; if (req.transaction.length) { // something else has already written to this array } }); 

但是,我真的不知道你怎么可能需要这个。 当你调用moduleAmoduleB ,你只需要传递一个对象作为参数,它就解决了你的问题。 也许你正在寻找dependency injection ?