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


Posted in NodeJs onJanuary 27, 2015

一,开篇分析

大家好,今天这篇文章主要是对"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“的全部源码,为了节省篇幅,注释已全部删掉,如下图:

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

补充一下:

 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),明天继续分析相关中间件,不断更新中 。。。 。。。

NodeJs 相关文章推荐
ubuntu下安装nodejs以及升级的办法
May 08 NodeJs
基于nodejs+express(4.x+)实现文件上传功能
Nov 23 NodeJs
Express与NodeJs创建服务器的两种方法
Feb 06 NodeJs
nodejs 图解express+supervisor+ejs的用法(推荐)
Sep 08 NodeJs
基于nodejs实现微信支付功能
Dec 20 NodeJs
nodejs+express搭建多人聊天室步骤
Feb 12 NodeJs
详解Nodejs内存治理
May 13 NodeJs
nodejs(officegen)+vue(axios)在客户端导出word文档的方法
Jul 31 NodeJs
nodejs中实现修改用户路由功能
May 24 NodeJs
typescript nodejs 依赖注入实现方法代码详解
Jul 21 NodeJs
nodejs制作小爬虫功能示例
Feb 24 NodeJs
Nodejs实现微信分账的示例代码
Jan 19 NodeJs
NodeJS学习笔记之Connect中间件模块(一)
Jan 27 #NodeJs
nodejs批量修改文件编码格式
Jan 22 #NodeJs
NodeJS学习笔记之MongoDB模块
Jan 13 #NodeJs
NodeJS学习笔记之(Url,QueryString,Path)模块
Jan 13 #NodeJs
NodeJS学习笔记之FS文件模块
Jan 13 #NodeJs
NodeJS学习笔记之Http模块
Jan 13 #NodeJs
Nodejs学习笔记之Stream模块
Jan 13 #NodeJs
You might like
php array_intersect()函数使用代码
2009/01/14 PHP
PHP 杂谈《重构-改善既有代码的设计》之五 简化函数调用
2012/05/07 PHP
解析yahoo邮件用phpmailer发送的实例
2013/06/24 PHP
Linux下PHP连接Oracle数据库
2014/08/20 PHP
PHP打开和关闭文件操作函数总结
2014/11/18 PHP
PHP基于rabbitmq操作类的生产者和消费者功能示例
2018/06/16 PHP
在你的网页中嵌入外部网页的方法
2007/04/02 Javascript
IE8 浏览器Cookie的处理
2009/01/31 Javascript
input+select(multiple) 实现下拉框输入值
2009/05/21 Javascript
JavaScript CSS修改学习第六章 拖拽
2010/02/19 Javascript
location.search在客户端获取Url参数的方法
2010/06/08 Javascript
Javascript模块化编程(三)require.js的用法及功能介绍
2013/01/17 Javascript
ExtJS4 动态生成的grid导出为excel示例
2014/05/02 Javascript
理解jQuery stop()方法
2014/11/21 Javascript
js生成验证码并直接在前端判断
2015/05/15 Javascript
jquery实现很酷的网页顶部图标下拉菜单效果
2015/08/22 Javascript
Bootstrap 组件之按钮(二)
2016/05/11 Javascript
Javascript将字符串日期格式化为yyyy-mm-dd的方法
2016/10/27 Javascript
微信小程序用户位置权限的获取方法(拒绝后提醒)
2018/11/15 Javascript
react-router-dom 嵌套路由的实现
2020/05/02 Javascript
[35:55]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第一场 12.11
2020/12/13 DOTA
python 控制语句
2011/11/03 Python
python用字典统计单词或汉字词个数示例
2014/04/22 Python
Python 时间操作例子和时间格式化参数小结
2014/04/24 Python
跟老齐学Python之私有函数和专有方法
2014/10/24 Python
python查找目录下指定扩展名的文件实例
2015/04/01 Python
解决Tensorflow使用pip安装后没有model目录的问题
2018/06/13 Python
Python 点击指定位置验证码破解的实现代码
2019/09/11 Python
pytorch中tensor.expand()和tensor.expand_as()函数详解
2019/12/27 Python
浅谈Python 函数式编程
2020/06/20 Python
Python中如何定义一个函数
2016/09/06 面试题
后进生转化工作制度
2014/01/17 职场文书
怎么写好自荐书
2014/03/02 职场文书
客户经理岗位职责
2015/01/31 职场文书
Python源码解析之List
2021/05/21 Python
Python中常见的反爬机制及其破解方法总结
2021/06/10 Python