请求路由的时候发生了什么
还是简单例子:
var express = require('express') var app = express() app.get('/', function (req, res) { res.send('hello world') }) app.listen(3000)
前面分析了定义这个路由的时候框架做的初始化和相关操作,现在来分析当server启动后,在浏览器里输入对应路径访问的时候会发生什么。
服务启动其实是由于调用了application.js文件里面的app.listen():
app.listen = function listen() { var server = http.createServer(this); return server.listen.apply(server, arguments); };
可以看到传递给http.createServer()的是this,也就是app,说到这个app对象,回到express.js里的主函数:
function createApplication() { var app = function(req, res, next) { app.handle(req, res, next); }; //新建一个app函数,参数里的req和res是原生的请求和相应对象原型的实例 //这个app函数作为参数被传进http.createServer里,也就是说app.handle()就是处理所有请求的中间件 mixin(app, EventEmitter.prototype, false); //将EventEmitter类的原型上的属性都合并入app中 mixin(app, proto, false); //proto是application.js导出的对象,带有很多属性,将这些属性合并到app上 // expose the prototype that will get set on requests app.request = Object.create(req, { app: { configurable: true, enumerable: true, writable: true, value: app } }) //request属性继承自原生请求对象,http.IncomingMessage.prototype // expose the prototype that will get set on responses app.response = Object.create(res, { app: { configurable: true, enumerable: true, writable: true, value: app } }) //response属性继承自原生响应对象,http.ServerResponse.prototype //上面的request属性和response属性都多加了一个app的数据属性指向app自己 app.init(); //app初始化 return app; //返回app函数 }
可以看出传递给http.createServer()的处理函数其实是app.handle(req, res, next)。
app.handle(req, res, next)