node.js 使 HTTP 服务器的请求和响应全局化?
我刚刚开始使用 Node.js 并运行了 http://nodebeginner.org/index.html 。很棒的入门教程,但我真的想知道是否可以将请求和响应设置为“全局”,以便为当前传入请求加载的任何模块都可以访问这些......而不是注入。
有想法吗?
I've just started on node.js and ran through http://nodebeginner.org/index.html. Great start tutorial but I really want to know is it possible to make both request and response 'global' so any module loaded for the current incoming request can access these... rather than injecting.
Ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
与大多数 Web 脚本语言不同,在 Node 中,来自不同客户端的许多 HTTP 请求可以同时处于“活动”状态。您如何知道您正在回复哪个客户?
因此,虽然您认为在任何给定时间只有 1 个请求和响应,但实际上所有当前客户端都有开放的请求。
Unlike most web-scripting language, in Node many HTTP requests from different clients can be 'active' at the same time. How would you ever know which client you're responding to?
So while you think there's only 1 request and response at any given time, there are actually open requests for all current clients.
由于异步事件循环,理论上可以使请求和响应变量全局可用……但是,一旦您从当前上下文返回(即使调用其他异步内容),队列中的下一个事件将是被执行。
现在考虑同时连接的另一个 HTTP 客户端。它将再次改变全局变量,你将失去旧的。所以最终,你的方法泄露了。
只有一个线程执行您自己的代码,显然一切都是线程安全的。但您仍然必须防止无效状态(变量等),因为您永远不知道下一个要执行的事件/回调是什么。
Due to the asynchronous event loop, it would be theoretically possible to make the reques and response varibale globally available… BUT, as soon as you return from your current context (even when calling other async stuff), the next event in the queue will be executed.
Now think of another HTTP client connecting in the meantime. It will change the global variables again and you will lose your old. So in the end, your approach is leaking.
Having only a single thread executing your own code, everything is obviously threadsafe. But you still have to protect against invalid states (variables etc.), because you never know what is the next event/callback to be executed.
节点域。
我意识到这是一个老问题,但没有一个答案是完全正确的。
事实上,您可以通过使用节点域来实现此功能。
全局变量通常被认为不好使用,因为它们破坏了封装,而正确封装的应用程序是良好设计的第一个构建块,因为应用程序将更易于阅读、测试和重构。
话虽这么说,我个人遇到过许多在单个请求范围内使用全局变量的良好用例。
例子
如果没有这个,通过多层代码跟踪单个请求就变得不可能,除非您将您的请求(或请求 ID)暴露给它不属于的层。 (即服务、DAL 等...将您的请求保留在您的控制器中(如果它属于的话)。
基本上,通过多层传递变量以便可以在应用程序的较低级别访问它们是不可持续的,并且会使代码非常混乱。
在您开始尖叫之前,是的,我知道从 Node 5 开始,域已被弃用,而且我也知道这并不是文档中记录的域的确切用例。但 Node 现在正在敲定一个新的 API,有望继续解决这个问题。
https://nodejs.org/api/domain.html
Node Domains.
This is an old question, I realize that, but none of the answers are completely correct.
The truth is that you can achieve this functionality by using Node Domains.
Global variables are generally considered bad to use because they break encapsulation and a properly encapsulated application is the first building block to a good design because the application will be easier to read, test, and refactor.
That being said I, I have personally come across many good use cases for using global variables within the scope of a single request.
Example
Tracking a single request through many layers of code becomes impossible without this, unless you expose your request (or req ID) to layers it just doesn't belong. (i.e. Service, DAL, etc... keep your request in your controller were it belongs).
Basically, Passing variables through many layers just so that they are accessible at the lower levels of my application is unsustainable and makes code very messy.
Before you start screaming, yes I am aware that Domains have been deprecated as of Node 5, and I am also aware that this is not the exact use case for Domains as it is documented. But the Node is finalizing a new API now, that will hopefully continue to solve this issue.
https://nodejs.org/api/domain.html
continuation-local-storage 解决了这个问题。如果我理解正确的话,与域有一些相似之处,只是它没有被弃用。 :D
这篇文章稍微解释一下。以及相关幻灯片。
continuation-local-storage solves this problem. If I understand correctly, there are some similarities to domains, only, it's not deprecated. :D
This post explains it a bit. And related slideshow.
这应该是可能的,但这需要一个数组来保存对响应和请求对象的引用。
然后你必须告诉模块索引在哪里可以找到数组中的对象。此外,您还必须清理阵列。因此,您确实无法避免将一些信息传递给模块。
最好将请求和响应对象引用直接传递给模块。
请记住,对象是通过引用传递的,因此将对象传递给函数/模块时不会有太大的开销。
It should be possible, but that would require an array to hold the references to the response and request objects.
And then you would have to tell the module the index where to find the objects in the array. Also you would have to cleanup the array. So you can't really avoid passing some info to the module.
Better pass the request and response object references directly to the module.
Keep in mind that objects are passed by reference, so there is not a big overhead when passing objects to functions/modules.