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 相关文章推荐
跟我学Nodejs(三)--- Node.js模块
May 25 NodeJs
nodejs教程之环境安装及运行
Nov 21 NodeJs
用NodeJS实现批量查询地理位置的经纬度接口
Aug 16 NodeJs
Nodejs中解决cluster模块的多进程如何共享数据问题
Nov 10 NodeJs
详解nodejs爬虫程序解决gbk等中文编码问题
Apr 06 NodeJs
Nodejs中使用captchapng模块生成图片验证码
May 18 NodeJs
详解Nodejs 通过 fs.createWriteStream 保存文件
Oct 10 NodeJs
nodeJS微信分享
Dec 20 NodeJs
Nodejs异步回调之异常处理实例分析
Jun 22 NodeJs
nodejs 如何手动实现服务器
Aug 20 NodeJs
使用koa-log4管理nodeJs日志笔记的使用方法
Nov 30 NodeJs
nodejs中实现修改用户路由功能
May 24 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
WampServer搭建php环境时遇到的问题汇总
2015/07/23 PHP
使用JavaScript创建新样式表和新样式规则
2016/06/14 PHP
PHP chunk_split()函数讲解
2019/02/12 PHP
模拟jQuery ajax服务器端与客户端通信的代码
2011/03/28 Javascript
jQuery EasyUI API 中文文档 - EasyLoader 加载器
2011/09/29 Javascript
Jquery显示和隐藏元素或设为只读(含Ligerui的控件禁用,实例说明介绍)
2013/07/09 Javascript
javascript内置对象arguments详解
2014/03/16 Javascript
jQuery实现的表头固定效果实例【附完整demo源码下载】
2016/08/01 Javascript
简单实现JS倒计时效果
2016/12/23 Javascript
详解使用vue-router进行页面切换时滚动条位置与滚动监听事件
2017/03/08 Javascript
超简单的Vue.js环境搭建教程
2017/03/17 Javascript
HTML5+Canvas调用手机拍照功能实现图片上传(下)
2017/04/21 Javascript
xmlplus组件设计系列之按钮(2)
2017/04/26 Javascript
JS组件系列之MVVM组件构建自己的Vue组件
2017/04/28 Javascript
使用JavaScript开发跨平台的桌面应用详解
2017/07/27 Javascript
Vue使用vue-cli创建项目
2017/09/01 Javascript
Sublime Text新建.vue模板并高亮(图文教程)
2017/10/26 Javascript
微信小程序如何获取openid及用户信息
2018/01/26 Javascript
vue组件之间通信实例总结(点赞功能)
2018/12/05 Javascript
详解js创建对象的几种方法及继承
2019/04/12 Javascript
vue把输入框的内容添加到页面的实例讲解
2019/11/11 Javascript
[01:02:17]2014 DOTA2华西杯精英邀请赛 5 24 DK VS VG
2014/05/26 DOTA
[03:24][TI9纪实] Dota奶爸
2019/08/22 DOTA
Python多线程编程(五):死锁的形成
2015/04/05 Python
Python根据文件名批量转移图片的方法
2018/10/21 Python
python框架django项目部署相关知识详解
2019/11/04 Python
pytorch中获取模型input/output shape实例
2019/12/30 Python
如何用 Python 处理不平衡数据集
2021/01/04 Python
Python实现Excel自动分组合并单元格
2021/02/22 Python
CSS3 Calc实现滚动条出现页面不跳动问题
2017/09/14 HTML / CSS
波兰最大的宠物用品网上商店:FERA.PL
2019/08/11 全球购物
企业文明单位申报材料
2014/05/16 职场文书
法院干警四风问题个人对照检查材料思想汇报
2014/10/07 职场文书
学习焦裕禄精神践行三严三实心得体会
2014/10/13 职场文书
python图像处理基本操作总结(PIL库、Matplotlib及Numpy)
2021/06/08 Python
Java中API的使用方法详情
2022/04/06 Java/Android