您好,欢迎访问一九零五行业门户网

NodeJS学习笔记之Connect中间件模块(二)_node.js

一,开篇分析
大家好,今天这篇文章主要是对connect中间件以及相关辅助中间件,做一个源码分析系列,我想上一篇文章大家也看了,
介绍了使用方式及用途,而这篇也是出于本人的兴趣,让读者对其有一个更深入的认识,如在分析阶段有什么不正确的地方,请大家多多指教,
好了!老规矩然我们进入正题。先来看一个例子,结合会用引入分析,如下:
复制代码 代码如下:
var connect = require(./lib/connect) ;
 var app = connect.createserver() ;
 app.use(connect.static(__dirname + /public,{
    maxage: 0 
})) ;
 app.use(function(req,res,next){
     res.end(hello world !) ;
 })
 .listen(8888) ;
二,逐行分析:
(1),第一行,引入connect模块,通过connect创建一个http|https server,提供http server的所有功能。
connect中间件允许你用多种方式创建server,
复制代码 代码如下:
var server = connect.createserver(
     connect.logger()
    , connect.static(__dirname + '/public')
) ; // 1
var app = connect() ;
app.use(function (req,res) {
    res.end(hello,大雄君 !\n)  ;
}).listen(8888)  ; // 2
那么它是如何做的那,看源码:
复制代码 代码如下:
exports = module.exports = createserver ;
exports.createserver = createserver ;
将“createserver”挂载到全局的“exports”上,然后再扩展一个“createserver”属性再次挂载,目的是为了兼容原生的书写形式,
达到了不同方式创建的目的。这也是大家在平时开发中可以借鉴的思想。
(2),再来看第二行connect.createserver,做了什么那,看如下源码:
复制代码 代码如下:
var httpserver = require('./http').server ,
 httpsserver = require('./https').server ;
 function createserver() {
   if ('object' == typeof arguments[0]) {
     return new httpsserver(arguments[0], array.prototype.slice.call(arguments, 1));
   } else {
     return new httpserver(array.prototype.slice.call(arguments));
   }
 };
httpsserver和httpserver基本一致,只是httpsserver封装的https的方法。在createserver的时候,同样可以传递进去一系列的中间件,和随后引入的效果是一样的,不过却只能绑定到根目录上。
(3),继续看第三行app.use(),做了什么那,看如下源码:
复制代码 代码如下:
var server = exports.server = function httpserver(middleware) {
   this.stack = [];
   middleware.foreach(function(fn){
     this.use(fn);
   }, this);
   http.server.call(this, this.handle);
 };
 /**
  * inherit from `http.server.prototype`.
  */
 server.prototype.__proto__ = http.server.prototype;
“connect是原型继承于http server的,它会用use到的中间件替换掉server的requestlistener。
通过connect.use(route, handle)来对每一个路由添加中间件,这些中间件handle会与route绑定保存在一个stack里面,每次有request请求的时候,
遍历这个堆,找到对应route的handle,执行handle,如果handle最后调用了next(),就会继续寻找并执行下一个匹配的handle。
通过封装handle,可以很容易的在connect基础上添加更多的middleware。
 (4),最后看看listen(8888),它做些什么工作那?
很简单,通过继承底层的server对象,赋予了listen的功能,监听特定端口。
server.prototype.__proto__ = http.server.prototype
 以下是”connect.js“的全部源码,为了节省篇幅,注释已全部删掉,如下图:
补充一下:
复制代码 代码如下:
fs.readdirsync(__dirname + '/middleware').foreach(function(filename){
   if (/\.js$/.test(filename)) {
     var name = filename.substr(0, filename.lastindexof('.'));
     exports.middleware.__definegetter__(name, function(){
       return require('./middleware/' + name);
     });
   }
 });
将middleware对象exports,然后循环定义给middleware对象一种方法,这种方法是直接加载 middleware 文件夹中的.js文件模块。
利用:exports.utils.merge(exports, exports.middleware) 这句话将middleware中的方法直接exports了。
三,总结一下:
 (1),理解源码的设计意图,有助于在应用上得到最大化的收获。
 (2),看源码时,理解流程再去扣语法细节。
 (3),借鉴源码中的巧妙实现思想,但不要过渡设计,为了设计而设计。
 (4),明天继续分析相关中间件,不断更新中 。。。 。。。
其它类似信息

推荐信息