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时间。