【发布时间】:2014-12-01 20:18:05
【问题描述】:
原始问题
我目前正在进行的项目是利用 Express 来管理 HTTP 请求。
该项目的结构有点复杂,但没有过多的细节,我们照常嵌入了很多 require 语句。我们遇到的最大问题是维护对请求和响应对象的访问。除了下面的例子,我们不太确定该怎么做。
var MyModule = require('my-module.js')(request);
是否可以将请求注入孩子及其后代的作用域?如果不使用全局变量(由于在并发请求期间会覆盖它),我们如何才能使这些后代可以访问某些变量?
编辑:
我正在使用一种模式,该模式需要不同范围的模块实例(特别是全局、会话和请求)。 require 创建一个实例并简单地返回该实例以供后续需求。在整个代码段的范围内,任意模块都必须在会话或请求级别可用,因为它们包含的数据。换句话说,在仍然使用require 的同时,我需要它们保持在特定范围内,以便并发请求无法访问和修改它们。然而,我需要保持与require 相同的基本功能,只是在更有限的范围内。
每次请求进入时都需要对它们进行实例化,而不是全局范围(就像现在一样),并且该实例应该为与该请求相关的每个 require 持续存在。
当前的解决方案是利用 express' req 来区分同一模块的多个实例以用于检索目的。如果为“这个特定请求”实例化了“这个特定实例”,那么这就是我们需要在需要时提供的实例。我们遇到的最大问题是,我们无法使请求可用于特定的需求链,以确保在需要时始终知道请求。目前,我们无法区分执行时需要拉入哪个请求实例。
我们能想到的唯一解决方案是找到一种方法以递归方式使请求可用于该执行链。但这是乏味且高度耦合的。似乎没有办法简单地说“对于这个执行链,我们将创建并使用所有这些实例”。
示例:
# ModuleA, ModuleB, and ModuleC are at the request level.
ModuleA requires ModuleC and changes a value.
ModuleB later requires ModuleC and attempts to retrieve that value.
这适用于全球范围内的事物,但我们会遇到并发请求的问题。因此,如果 RequestA 在 RequestB 尝试从 ModuleC 检索值之前修改了 ModuleC,则 RequestB 将检索 RequestA 的值。当我们开始处理会话等时,这可能真的很讨厌。我们不希望 Bob 能够访问 George 的 User 对象实例。
我们想要避免的:
RequestA comes in -> ModuleA changes property value of ModuleC.foo to "bar"
RequestB comes in -> ModuleA changes property value of ModuleC.foo to "hello"
RequestA later -> ModuleB retrieves value of ModuleC.foo
RequestA expects -> ModuleC.foo = "bar"
Instead -> ModuleC.foo = "hello"
【问题讨论】:
-
我不确定我是否理解您的问题 - 您是否试图让请求对象在整个
my-module.js中都可以访问?您应该能够在模块中创建一个命名空间 (this.request) 变量来跟踪请求。然后将其传递给您在那里调用的任何模块并执行相同的操作。如果您想在不显式传递所述对象的情况下跨模块保留对对象的访问,则在某些时候您将不得不使用全局空间。这就是 JS 的工作原理。完全披露:我没有深入的构建自定义节点模块的经验,所以我在这里可能是错的。 -
我想我可能刚刚找到了我的解决方案...
module.parent[nodejs.org/api/modules.html] -
@JordanForeman 确实如此。我试图避免的是每次都必须将它传递给每个单独的 require 语句。希望,但是利用 module.parent,我可以简单地将它传递给初始的
required模块,然后如果没有明确传递,孩子可以简单地从父模块中提取它。 -
我什至不知道它的存在!这将比在每个模块中存储对对象的引用更有效。感谢您今天教我一些东西:)
-
@JordanForeman 我也没有!哈哈
标签: javascript node.js express dependency-injection scope