سؤال

I decided the best way to learn node was to just re-build one of my existing c# / webforms apps in node.

It's been quite a learning curve, and one thing i've noticed i use a lot in c# is HttpContext.Current to access things like Session and Request.Url in classes or static methods.

Is there anything like this in node that i'm missing?

I've split my node app into reusable "classes" like this (pseudo code)

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

and then in one of my controllers

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

Now, if i wanted to access session or the url in userManager, i have to do something like this:

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

This isn't a huge problem but i'm just curious if there's another way, or if i'm structuring my app completely wrong it would be cool to get some insight as to how others are doing things.

هل كانت مفيدة؟

المحلول

It's normal. Here's why:

HttpConext.Current in Asp.net works because it is able to associate a particular worker thread with data, in this case the entire context of the request. This happens early in the page life cycle. Code can always ask, "what's my context" this way.

Nodejs, as it runs JavaScript in a single thread, has no equivalent to the thread local storage used by .NET. If only one request was processed at a time, the request and response values could be stored globally and accessed from anywhere.

However, as you know, the efficiency of NodeJs comes from the fact that the engine stays busy by doing async work in engine controlled threads. Further, as many async operations are IO, they are often waiting for the results of the IO operation to return. During that wait, the engine picks up work off the queue and executes it until the next async operation. Generally speaking, it would be difficult to predict what code was going to execute from the queue next. It wouldn't know the context of the code being executed without another NodeJS feature.

Without thread local storage to manage state, and without the ability to proper adjust global state for the "now" current request being served, the engine relies on JavaScript closures. These capture the context and scope, and are preserved through the execution of queued work and restored when the engine returns results to a block of code. Interestingly, Microsoft, had anonymous functions (reference) been available when Asp.Net was first created, could have followed a similar pattern to NodeJs.

So, there's not really a place to store a request's state globally without doing some association of the current JavaScript to the original request. A closure would be necessary. But, at that point, you might as well just pass the two values around, or combine them into a single context = { request : req, response : res }. It would be normal to pass the values around as required.

نصائح أخرى

The most typical way to solve this problem is to pass req and res around since they define the context. Passing those explicitly is tiresome and usually all functions are just defined in request handler scope.

But now you can actually have something like thread-local storage: continuation-local storage. It requires at least node 0.11.9 or AsyncListener API polyfill for older versions.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top