2013-11-27 37 views
2

我决定学习节点的最佳方式就是在节点中重新构建一个现有的c#/ webforms应用程序。HttpContext.Current与节点中的对象相似

这是一个相当的学习曲线,有一件事我注意到我在c#中使用了很多东西,它是HttpContext.Current,用类或静态方法访问类似SessionRequest.Url的东西。

有没有像这样的节点,我失踪了?

我拆我的节点应用成可重用的“类”这样的(伪代码)

/api/ 
    - user-manager.js 
    - getAllUsers() 

,然后在我的控制器之一现在

var userManager = require('user-manager'); 
var users = userManager.getAllUsers(); 

,如果我想访问会话或的UserManager的URL,我必须做这样的事情:

var users = userManager.getAllUsers(req, res); 

这是不是一个巨大的问题,但我只是好奇,如果有另一种方式,或者如果我完全错误地构建我的应用程序,得到一些有关别人如何做事的见解将是很酷的。

+0

如果'userManager.getAllUsers'需要访问'req'或'res',那么你的抽象是有漏洞的。只传递给它需要的值。 – Bulkan

+0

@Bulkan同意!没有想到这一点。不管怎样,你知道任何能够回答我的问题吗? – seanxe

回答

7

这很正常。原因如下:

HttpConext.Current在Asp.net中的工作原理是因为它能够将特定的工作线程与数据相关联,在这种情况下,该请求的整个上下文都是这样。这发生在页面生命周期的早期。代码总是可以这样问,“我的背景是什么”。因为它在单线程中运行JavaScript,所以Nodejs与.NET所使用的线程本地存储没有任何等价关系。如果一次只处理一个请求,则requestresponse值可以全局存储并可以从任何地方访问。然而,如你所知,NodeJs的效率来自这样一个事实,即引擎通过在引擎控制的线程中执行异步工作而保持繁忙。而且,由于许多异步操作是IO,他们通常会等待IO操作的结果返回。在等待期间,引擎从队列中取出工作并执行它直到下一个异步操作。一般来说,很难预测接下来要从队列中执行什么代码。如果没有其他NodeJS功能,它将不知道正在执行的代码的上下文。

如果没有线程本地存储来管理状态,并且没有适当调整正在服务的“当前”当前请求的全局状态的能力,那么引擎依赖于JavaScript关闭。这些捕获上下文和范围,并通过执行排队工作来保留,并在引擎将结果返回到代码块时恢复。有趣的是,当Asp.Net第一次创建时,Microsoft可以使用匿名函数(reference),可以采用类似于NodeJs的模式。

因此,如果没有将当前JavaScript与原始请求进行关联,就没有真正的地方来存储请求的状态。封闭将是必要的。但是,在这一点上,你可能只是传递这两个值,或将它们合并成一个单一的context = { request : req, response : res }。根据需要传递值是正常的。

+0

+1。这是一个非常棒的答案。感谢您的解释 - 现在我的脑海里已经完全清楚了! – seanxe

+0

谢谢,我有同样的问题,这个答案很清楚。 –

0

解决此问题的最常见方法是通过reqres,因为它们定义了上下文。明确地传递它们是令人厌烦的,通常所有的函数都只是在请求处理器范围中定义的。

但现在你实际上可以拥有线程本地存储:continuation-local storage。对于旧版本,它至少需要节点0.11.9或AsyncListener API polyfill