Node.js Connect createServer code
Asked Answered
A

1

0

I'm reading Node.js Connect version 2.15.0:

/**
 * Create a new connect server.
 *
 * @return {Function}
 * @api public
 */

function createServer() {
  function app(req, res, next){ app.handle(req, res, next); }
  utils.merge(app, proto);
  utils.merge(app, EventEmitter.prototype);
  app.route = '/';
  app.stack = []; 
  for (var i = 0; i < arguments.length; ++i) {
    app.use(arguments[i]);
  }
  return app;
};

A few questions:

  1. app.handle seems to be provided in proto, since there is app.handle defined in proto.js. So, this is a use of a closure, and app.handle is defined not at the time Node parses function app() but later on in the code? Also app itself is defined in..uh..function app(). The code seems funny to me.

  2. When is function app() invoked? All I know create server creates the server. So when would I be invoking that function and how? Do I do something like:

    app = createServer()
    app.listen(3000)
    app(req, res, next)
    
  3. utils.merge() simply says

    exports.merge = function(a, b){ 
      if (a && b) {
        for (var key in b) {
          a[key] = b[key];
        }   
      }
      return a;
    };
    

    Is that a common practice to do instead of inheritance or what? It looks like mixin to me.

Affiant answered 13/5, 2014 at 8:48 Comment(0)
S
0
  1. app.handle seems to be provided in proto, since there is app.handle defined in proto.js. So, this is a use of a closure, and app.handle is defined not at the time Node parses function app() but later on in the code? Also app itself is defined in..uh..function app(). The code seems funny to me.

Yes, app.handle comes from proto. But no, accessing app inside the app function is not a closure, a function is available by its name in all function declarations.

2. When is function app() invoked? All I know createServer creates the server. So when would I be invoking that function and how?

The connect docs use this example code:

var app = connect();
…
http.createServer(app).listen(3000);

You can see that connect (which is the createServer function you posted) does create the app, which is passed as a handler to the actual http server.

3. Is utils.merge() a common practice instead of inheritance or what? It looks like mixin to me.

Yes, merge does mixin one object into the other. This is done to extend the function object app with all the necessary methods. It is necessary because it is impossible to Define a function with a prototype chain in a standard way. They might have used something along these lines as well:

app.__proto__ = utils.merge(Object.create(EventEmitter.prototype), proto);

but then app wouldn't any longer be instanceof Function; and have no function methods.

Syrian answered 13/5, 2014 at 10:1 Comment(2)
Thanks for 1. I need to chew a bit on 3. For 2, var app is a result for the createServer() function I posted. How does http.createServer() execute the line app.handle(req, res, next) inside the createServer() I posted?Affiant
http.createServer(…) is equivalent to (new http.Server).addListener('request', …). Hunt down where/how this event is emitted yourself.Syrian

© 2022 - 2024 — McMap. All rights reserved.