understanding expressJS (1)

Working like don’t need money, dancing like no one’s watching, love like never get hurt

这里主要了解一下启动一个express 应用的过程

//express.js
function createApplication() {
  var app = function(req, res, next) {
    app.handle(req, res, next);
  };

  mixin(app, EventEmitter.prototype, false);
  mixin(app, proto, false);

  app.request = { __proto__: req, app: app };
  app.response = { __proto__: res, app: app };
  app.init();
  return app;
}

express.js 实际上定义导出了一个createApplication的函数。express()实际上是得到了一个app的实例。

mixin(app, proto, false);

这段代码的作用就是把application.js下定义的属性扩展到app上。

// bin/www
var server = http.createServer(app);

http.createServer 接受一个函数作为request事件的回调函数。实际下面这种写法也是一样的。

var server = http.createServer();
server.on('request', app);

这里传到createServer的app就是上面得到的app实例(实际就是一个函数)。在接收到http请求时会执行app.handle 方法。app.handle 方法定义如下:

//application.js
app.handle = function(req, res, done) {
  var router = this._router;

  // final handler
  done = done || finalhandler(req, res, {
    env: this.get('env'),
    onerror: logerror.bind(this)
  });

  // no routes
  if (!router) {
    debug('no routes defined on app');
    done();
    return;
  }

  router.handle(req, res, done);
};

this._router(即app._router)实际上是在app.lazyrouter方法中new的一个Router对象, 一般在定义中间件的时候会用到这个方法来给app添加一个_router属性。 所以上面的app.handle 其实是router.handle的一个代理方法,最终还是调用的router.handle()。至于具体处理请求的过程另写一遍具体介绍。

回到www/bin文件

var port = normalizePort(process.env.PORT || '3001');
app.set('port', port);

var server = http.createServer(app);

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

这里首先增加port属性到app.js。 然后创建一个http server 并监听它的request, err, listening时间。