nodejs 发展很快,从 npm 上面的包托管数量就可以看出来。不过从另一方面来看,也是反映了 nodejs 的基础不稳固,需要开发者创造大量的轮子来解决现实的问题。
知其然,并知其所以然这是程序员的天性。所以把常用的模块拿出来看看,看看高手怎么写的,学习其想法,让自己的技术能更近一步。
引言
express 是 nodejs 中最流行的 web 框架。express 中对 http 中的 request 和 response 的处理,还有以中间件为核心的处理流程,非常灵活,足以应对任何业务的需求。
而 connect 曾经是 express 3.x 之前的核心,而 express 4.x 已经把 connect 移除,在 express 中自己实现了 connect 的接口。可以说 connect 造就了 express 的灵活性。
因此,我很好奇,connect 是怎么写的。
争取把每一行代码都弄懂。
connect 解析
我们要先从 connect 的官方例子开始
var connect = require( 'connect' ); var http = require( 'http' ); var app = connect(); // gzip/deflate outgoing responses var compression = require( 'compression' ); app.use(compression()); // store session state in browser cookie var cookieSession = require( 'cookie-session' ); app.use(cookieSession({ keys: [ 'secret1' , 'secret2' ] })); // parse urlencoded request bodies into req.body var bodyParser = require( 'body-parser' ); app.use(bodyParser.urlencoded({extended: false })); // respond to all requests app.use( function (req, res){ res.end( 'Hello from Connect!/n' ); }); //create node.js http server and listen on port http.createServer(app).listen(3000);
从示例中可以看到一个典型的 connect 的使用:
var app = connect() // 初始化 app.use( function (req, res, next) { // do something }) // http 服务器,使用 http.createServer(app).listen(3000);
先倒着看,从调用的地方更能看出来,模块怎么使用的。我们就先从 http.createServer(app) 来看看。
从 nodejs doc 的官方文档中可以知, createServer 函数的参数是一个回调函数,这个回调函数是用来响应 request 事件的。从这里看出,示例代码中 app 中函数签就是 (req, res) ,也就是说 app 的接口为 function (req, res) 。
但是从示例代码中,我们也可以看出 app 还有一个 use 方法。是不是觉得很奇怪,js 中函数实例上,还以带方法,这在 js 中就叫 函数对象,不仅能调用,还可以带实例变量。给个例子可以看得更清楚:
function handle () { function app(req, res, next) { app.handle(req, res, next)} app.handle = function (req, res, next) { console.log( this ); } app.statck = []; return app; } var app = handle(); app() // ==> { [Function: app] handle: [Function], stack: [] } app.apply({}) // ==>{ [Function: app] handle: [Function], stack: [] }
新闻热点
疑难解答
图片精选