2

This is something that has been bothering me and I cant seem to find a straight answer.

Here is a form of Node function that I use a lot, it handles a web request and does a bit of IO:

function handleRequest(req, res) {
    doSomeIo()
       .then(function(result) {
           res.send(result)
       })
}

This function gets called and the res parameter is set to the current response object and it goes of into the land of IO, while its playing out there a second request comes through and sets the res to a new object? Now the first request comes back from IO, and uses the res object, is this now the first instance or the second i.e. does node essentially make a separate copy of everything each time the handleRequest function is called, with its own parameter values or is there only one instance of it and its parameters? Are the parameters in the the above function safe in an async environment or would it be better to do something like this:

function handleRequest(req, res) {
        doSomeIo()
           .then(function(res) {
               return function(result) {
                   res.send(result)
               }
           }(res))
    }

Or am I just completely ignorant of how Node and Java Script works, which seems pretty likely.

  • 1
    Why would a second request coming in replace the one you reference in your function? Your function never loses a reference to the original request. Whenever a new request comes in, a new object is created without interfering with any other objects. – Mike Cluck Oct 11 '16 at 15:55
  • Thanks for confirming that, I was worried that I may be writing unsafe code and couldn't find any confirmation one way or the other. Does that also apply to local function variables or only parameters? – Christopher Nash Oct 11 '16 at 16:02
  • Both. Really, you can think of parameters as local variables that were declared in the function declaration. The same scoping rules apply to them. – Mike Cluck Oct 11 '16 at 16:04
  • 1
    Thank you all for your helpful comments I feel a lot more comfortable. – Christopher Nash Oct 11 '16 at 16:12
  • Glad I could help :) – Mike Cluck Oct 11 '16 at 16:13

3 Answers3

2

You don't have to worry at all about this case. The req object contains information about the HTTP request that the server received. Everything is sandboxed in per request basis. This will be helpful for you: What are "res" and "req" parameters in Express functions?

Community
  • 1
  • 1
Stavros Zavrakas
  • 2,747
  • 1
  • 11
  • 27
0

You can expect the current req and res object to remain the same among multiple events (I/O responses are essentially events) unless you do something to them, or you have other middleware that does something. There's no need to do anything like your second code snippet.

If you're new to JavaScript and/or the concept of closures, that's probably why you're uneasy with the syntax.

john_omalley
  • 1,308
  • 6
  • 13
0

Each call to the function handleRequest() will not use the same variable values of previous calls to handleRequests(). An easy way to see this behavior would be to log the number of times the method was called, and the value of an incrementer in handleRequest().

Example:

In app.js (or whatever js file you initialize your server in), add the following:

var app = express(),
    calls = 0; app.set('calls', calls);

Then in your handler add the following:

function handleRequest(req, res) {
        doSomeIo()
           .then(function(res) {
               req.calls++;

               return function(result) {
                   res.send(req.calls)
               }
           }(res))
    }

You should notice that each call to the endpoint, no matter how quickly you make each call, count increases by 1 each time (get ready for race conditions).

Patrick Motard
  • 2,630
  • 2
  • 12
  • 23