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 相关文章推荐
使用upstart把nodejs应用封装为系统服务实例
Jun 01 NodeJs
Google官方支持的NodeJS访问API,提供后台登录授权
Jul 29 NodeJs
Nodejs Express4.x开发框架随手笔记
Nov 23 NodeJs
nodejs的压缩文件模块archiver用法示例
Jan 18 NodeJs
用nodeJS搭建本地文件服务器的几种方法小结
Mar 16 NodeJs
深入nodejs中流(stream)的理解
Mar 27 NodeJs
nodejs制作爬虫实现批量下载图片
May 19 NodeJs
Windows下快速搭建NodeJS本地服务器的步骤
Aug 09 NodeJs
nodejs对express中next函数的一些理解
Sep 08 NodeJs
typescript nodejs 依赖注入实现方法代码详解
Jul 21 NodeJs
Nodejs监听日志文件的变化的过程解析
Aug 04 NodeJs
Nodejs中使用puppeteer控制浏览器中视频播放功能
Aug 26 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
phpMyAdmin 链接表的附加功能尚未激活问题的解决方法(已测)
2012/03/27 PHP
基于PHP的简单采集数据入库程序
2014/07/30 PHP
PHP正则表达式替换站点关键字链接后空白的解决方法
2014/09/16 PHP
php下Memcached入门实例解析
2015/01/05 PHP
PHP实现链式操作的三种方法详解
2017/11/16 PHP
AJAX分页的代码(后台asp.net)
2011/02/14 Javascript
在JavaScript里防止事件函数高频触发和高频调用的方法
2014/09/06 Javascript
JS给超链接加确认对话框的方法
2015/02/24 Javascript
深入浅析JavaScript中的scrollTop
2016/07/11 Javascript
jQuery Easyui使用(一)之可折叠面板的布局手风琴菜单
2016/08/17 Javascript
jquery UI Datepicker时间控件冲突问题解决
2016/12/16 Javascript
jQuery中select与datalist制作下拉菜单时的区别浅析
2016/12/30 Javascript
非常实用的vue导航钩子
2017/03/20 Javascript
详解Angular.js中$http拦截器的介绍及使用
2017/07/04 Javascript
利用原生js实现html5小游戏之打砖块(附源码)
2018/01/03 Javascript
Node.js文件编码格式的转换的方法
2018/04/27 Javascript
深入理解Vue.js轻量高效的前端组件化方案
2018/12/10 Javascript
layUI实现前端分页和后端分页
2019/07/27 Javascript
vue之debounce属性被移除及处理详解
2019/11/13 Javascript
Python urllib模块urlopen()与urlretrieve()详解
2013/11/01 Python
跟老齐学Python之有容乃大的list(2)
2014/09/15 Python
使用pandas中的DataFrame数据绘制柱状图的方法
2018/04/10 Python
python之cv2与图像的载入、显示和保存实例
2018/12/05 Python
python实现读取excel文件中所有sheet操作示例
2019/08/09 Python
小 200 行 Python 代码制作一个换脸程序
2020/05/12 Python
HTML5中外部浏览器唤起微信分享功能的代码
2020/09/15 HTML / CSS
西尔斯百货官网:Sears
2016/09/06 全球购物
最新的小工具和卓越的产品设计:Oh That Tech!
2019/08/07 全球购物
外企测试工程师面试题
2015/02/01 面试题
党员教师群众路线对照检查材料思想汇报
2014/09/29 职场文书
普通党员群众路线教育实践活动心得体会
2014/11/04 职场文书
前台接待员岗位职责
2015/04/15 职场文书
学雷锋广播稿大全
2015/08/19 职场文书
Python合并pdf文件的工具
2021/07/01 Python
i5-10400f处理相当于i7多少水平
2022/04/19 数码科技
shell进度条追踪指令执行时间的场景分析
2022/06/16 Servers