Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/421.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript NodeJS Express中每个请求的全局范围_Javascript_Node.js_Express_Global Variables - Fatal编程技术网

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

Javascript NodeJS Express中每个请求的全局范围,javascript,node.js,express,global-variables,Javascript,Node.js,Express,Global Variables,我有一个基本的express服务器,在每次请求处理期间需要存储一些全局变量。 更深入地说,请求处理涉及许多需要存储在变量中的操作,例如global.transaction[] 当然,如果我使用global作用域,每个连接都将共享其事务的信息,我需要一个全局作用域,因为我需要在执行期间从许多其他模块访问事务数组 对这个问题有什么建议吗?我觉得这是一件非常琐碎的事情,但我正在寻找复杂的解决方案:) 非常感谢 更新 更清楚地说,这是一个案例场景 根据每个请求,我有3个模块(ModuleA,Module

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

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

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

非常感谢

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

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


因此,
ModuleA/B/C
需要访问一种全局变量,但是
request_1
request_2
request_3
等的列表。。。不要混淆。

以下是我的建议避免像火一样的全球状态

  • 根据我的经验,这是节点服务器的首要维护问题
  • 它使您的代码不可组合,更难重用
  • 它在您的代码中创建了隐式依赖关系——您永远无法确定哪一部分依赖于哪一部分,并且不容易验证
您希望应用程序的每个部分使用的代码部分尽可能明确。这是个大问题

问题 我们希望跨多个请求同步状态并相应地采取行动。在编写软件时,这是一个非常大的问题——有人说甚至是最大的问题。应用程序中对象通信方式的重要性无论怎样估计都不为过

一些解决方案 有几种方法可以在节点服务器中跨请求或服务器范围共享状态。这取决于你想做什么。以下是两个最常见的例子

  • 我想观察这些请求的作用
  • 我想要一个请求根据另一个请求做的事情来做
  • 1.我想观察这些请求的作用 同样,有很多方法可以做到这一点。以下是我看到最多的两个

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

    您可以执行以下操作:

    request.emit("Client did something silly",theSillyThing)l
    
    如果你愿意的话,从外面听

    使用观察者模式 这类似于事件发射器,但与之相反。在请求上保留一个依赖项列表,并在请求上发生有趣的事情时自己对其调用处理程序方法

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

    2.我想要一个请求根据另一个请求做的事情来做。 这比仅仅倾听要有趣得多。同样,这里有几种方法。他们的共同点是我们将共享放在一个服务中

    而不是全局状态-每个请求都可以访问服务-例如,当您读取一个文件时,您会通知服务,当您需要读取文件的列表时,您会请求服务。依赖项中的所有内容都是显式的

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

    好理论!那么我的用例呢? 对于你的情况,我有两个选择。这远远不是唯一的解决办法

    第一种选择:

    • 每个模块都是一个事件发射器,每当它们读取文件时都会发出一个事件
    • 服务会侦听所有事件并保持计数
    • 请求可以显式访问该服务,并可以查询该服务中的文件列表
    • 请求通过模块本身而不是添加的服务执行写操作
    第二种选择:

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

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

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

    下面是一个示例(使用Express):


    然而,我真的不明白你怎么会需要这个。当您调用
    moduleA
    moduleB
    时,只需将一个对象作为参数传递,它就解决了您的问题。也许您正在寻找?

    为什么global不能满足您的需求?此外,您还可以在express中使用app.locals(我很好奇为什么它不符合您的要求)?理想情况下,如果可能的话,应该避免使用全局变量。看起来这个任务不应该由数据库处理吗?这还将允许应用程序水平扩展,目前无法实现,因为需要将所有内容存储到一个变量中,而这个变量不能在多个服务器之间共享。我根本不打算使用数据库,因为这是一个更大项目的一部分,我只需要处理内存中的变量。你不能在处理函数中将文件名作为局部变量读取吗?2015年注意-我会使用可观察的而不是事件发射器-例如,查看RxJS或BaconJS
    app.get('/hello.txt', function(req, res){
        req.transaction = req.transaction || [];
    
        if (req.transaction.length) {
            // something else has already written to this array
        }
    });