NodeJS Express中每个请求的全局范围
我有一个基本的快递服务器,需要在每个请求处理期间存储一些全局variables。 更深入地说,请求处理涉及许多操作,需要存储在一个variables中,如global.transaction[]
当然,如果我使用global
范围,每个连接将共享其事务的信息,我需要一个全局范围,因为我需要在执行期间从许多其他模块访问事务数组。
有关这个问题的任何build议? 我觉得是非常微不足道的,但我正在寻找复杂的解决scheme:)
非常感谢!
更新这是一个案例情况,更清楚。
每个请求我有3个模块( ModuleA
, ModuleB
, ModuleC
),它读取一个目录中的10个随机文件的内容。 我想跟踪每个请求读取的文件名列表,并发送res.write
列表。
因此, ModuleA/B/C
需要访问一个全局variables,但request_1
, request_2
, request_3
等列表不必混淆。
这是我的build议避免像火灾一样的全球状态 。
- 从我的经验来看,这是Node服务器中的头号维护问题。
- 它使您的代码不可组合,更难以重用。
- 它会在你的代码中创build隐含的依赖关系 – 你永远不能确定哪个部分取决于哪个部分,而且不容易validation。
您希望应用程序使用的代码部分尽可能的明确 。 这是一个很大的问题。
问题
我们希望跨多个请求同步状态并采取相应的行动。 这是编写软件时遇到的一个非常大的问题 – 有人甚至说是最大的问题。 对象在应用程序交stream中的重要性不能被高估。
一些解决scheme
有几种方法可以在Node服务器上跨越请求或服务器范围完成共享状态。 这取决于你想要做什么。 这是两个最常见的imo。
- 我想观察请求的作用。
- 我想要一个基于另一个请求做什么的请求。
我想观察请求的作用
再次,有很多方法可以做到这一点。 这是我最看重的两个。
使用事件发射器
这样请求发出事件。 应用程序读取请求触发的事件并相应地了解它们。 应用程序本身可以是一个可以从外部观察的事件发射器。
你可以做一些事情:
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 } });
但是,我真的不知道你怎么可能需要这个。 当你调用moduleA
或moduleB
,你只需要传递一个对象作为参数,它就解决了你的问题。 也许你正在寻找dependency injection ?