8

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

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

对这个问题有什么建议吗?我觉得这是一件非常微不足道的事情,但我正在寻找复杂的解决方案:)

非常感谢!

更新 这是一个案例场景,更清楚。

在每个请求中,我都有 3 个模块 ( ModuleA, ModuleB, ModuleC),它们读取一个目录中 10 个随机文件的内容。我想跟踪每个请求读取的文件名列表,并与res.write列表一起发回。

所以ModuleA/B/C需要访问一种全局变量,但,request_1等列表不必混淆。request_2request_3

4

2 回答 2

11

这是我的建议,避免像火一样的全局状态

  • 根据我的经验,这是 Node 服务器中的头号维护问题。
  • 它使您的代码不可组合并且更难重用。
  • 它会在您的代码中创建隐式依赖关系——您永远无法确定哪一部分依赖于哪一部分,并且不容易验证。

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

问题

我们希望跨多个请求同步状态并采取相应措施。这是编写软件的一个非常大的问题——有人说甚至是最大的问题。应用程序中对象通信方式的重要性不能被高估。

一些解决方案

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

  1. 我想观察请求的作用。
  2. 我希望一个请求根据另一个请求所做的事情来做事。

1.我想观察requests做了什么

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

使用事件发射器

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

您可以执行以下操作:

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

如果你愿意的话,然后从外面听。

使用观察者模式

这就像一个事件发射器,但相反。您保留请求的依赖项列表,并在请求发生有趣的事情时自己调用处理程序方法。

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

2. 我希望一个请求根据另一个请求所做的事情来做事。

这比只听要复杂得多。同样,这里有几种方法。他们的共同点是我们将共享放在服务中

而不是拥有全局状态 - 每个请求都可以访问服务 - 例如,当您读取文件时通知服务并且当您想要读取文件的列表时 - 您询问服务。依赖项中的所有内容都是明确的。

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

好理论!现在我的用例呢?

对于您的情况,有两种选择。这远非唯一的解决方案。

第一个选项:

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

第二种选择:

  • 创建一个拥有 module1、module2 和 module3 副本的服务。(作品)
  • 该服务根据模块的要求将操作委托给模块。
  • 该服务保留自通过它发出请求以来访问的文件列表。
  • 请求停止直接使用模块 - 改为使用服务。

这两种方法都有优点和缺点。可能需要一个更复杂的解决方案(这两个在实践中非常简单),其中服务被进一步抽象,但我认为这是一个好的开始。

于 2013-11-12T10:40:16.103 回答
0

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

这是一个示例(使用 Express):

app.get('/hello.txt', function(req, res){
    req.transaction = req.transaction || [];

    if (req.transaction.length) {
        // something else has already written to this array
    }
});

但是,我真的不明白你怎么会需要这个。当您调用moduleAormoduleB时,您只需传递一个对象作为参数,它就可以解决您的问题。也许您正在寻找依赖注入

于 2013-11-12T13:09:25.427 回答