10

I understand the essence of callback functions in that the function is executed again after being passed as the parameter to another function. However, I'm confused as to where the variables inside the callback function come from as shown in the following node.js example:

router.get('/', function(req, res){
    res.render('index', {});
});

How do the variables req and res get populated? An example explaining how I can just call res.render(...) without declaring res myself would be greatly appreciated.

Danny Liu
  • 499
  • 2
  • 5
  • 12
  • 1
    The parameters come from the Node runtime libraries. They respond to the actual network activity, put together the request and response objects, and then invoke your callback function. – Pointy Jan 06 '16 at 02:27
  • `arguments[1].render(...)` is an option. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments – Ram Jan 06 '16 at 02:29
  • When express detects an request on the / route it will call your function with the req parameter and the res parameter. Just as you would call a regular JavaScript function like `function add(num1,num2){return num1 + num2};add(2+3);` – E. Sundin Jan 06 '16 at 02:30
  • Closely related, possibly duplicate of: [How are input parameters filled in javascript method chains?](/q/21358027/4642212). – Sebastian Simon Jan 29 '23 at 14:05

3 Answers3

9

They come from the same place they come from when a normal non callback function is invoked, at invocation time.

If you have this function,

function add (a, b) {
  return a + b
}

You're fine with knowing that a and b come from when you invoke add,

add(1,2)

and it's the same principle with callbacks, don't let your brain get all twisted just because it's getting invoked later.

At some point the function you pass to router.get is going to be invoked, and when it does, it will receive req and res.

Let's pretend the definition for router.get looks like this

router.get = function(endpoint, cb){
   //do something
   var request = {}
   var response = {}
   cb(request, response) // invocation time
}

In the case of your example, it's just up to node to pass your function request and response whenever .get is invoked.

Tyler McGinnis
  • 34,836
  • 16
  • 72
  • 77
1

They get populated by whatever code is calling the callback. In your example, this is something inside the Express framework, though Express uses the node http library under the hood and adds additional functionality to the request and response objects provided by it.

But in code you write you can create a callback function signature that takes whatever params you want.

Paul
  • 35,689
  • 11
  • 93
  • 122
  • Express does no longer depend on connect as of [version 4](http://expressjs.com/en/guide/migrating-4.html#changes). – E. Sundin Jan 06 '16 at 02:35
1

The whole point of the callback is that the invoked function calls it back.

In the case of router.get, it will insert the route (path, method, callback) in a lookup table; when a request comes in, Express will construct the response object, match the request's path and method against all the entries in the lookup table, take the callback from the matching entry and invoke callback(request, response) (passing the detected request and created response).

Amadan
  • 191,408
  • 23
  • 240
  • 301