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 20 NodeJs
跟我学Nodejs(三)--- Node.js模块
May 25 NodeJs
Google官方支持的NodeJS访问API,提供后台登录授权
Jul 29 NodeJs
windows 下安装nodejs 环境变量设置
Feb 02 NodeJs
nodejs中全局变量的实例解析
Mar 07 NodeJs
nodejs搭建本地http服务器教程
Mar 13 NodeJs
nodejs批量下载图片的实现方法
May 19 NodeJs
nodejs中Express与Koa2对比分析
Feb 06 NodeJs
nodeJs实现基于连接池连接mysql的方法示例
Feb 10 NodeJs
NodeJS加密解密及node-rsa加密解密用法详解
Oct 12 NodeJs
Nodejs技巧之Exceljs表格操作用法示例
Nov 06 NodeJs
浅谈Node的内存泄露问题
May 06 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与数据库代码开发规范
2013/08/08 PHP
PHP数组操作简单案例分析
2016/10/15 PHP
PHP经典设计模式之依赖注入定义与用法详解
2019/05/21 PHP
laravel5.6 框架邮件队列database驱动简单demo示例
2020/01/26 PHP
javascript阻止浏览器后退事件防止误操作清空表单
2013/11/22 Javascript
nodejs实现黑名单中间件设计
2014/06/17 NodeJs
jQuery简单实现网页选项卡特效
2014/11/24 Javascript
让图片跳跃起来  javascript图片轮播特效
2016/02/16 Javascript
解读Bootstrap v4 sass设计
2016/05/29 Javascript
javascript简单实现跟随滚动条漂浮的返回顶部按钮效果
2016/08/19 Javascript
TypeScript入门-接口
2017/03/30 Javascript
Javascript实现页面滚动时导航智能定位
2017/05/06 Javascript
vue使用中的内存泄漏【推荐】
2018/07/10 Javascript
Vue插件打包与发布的方法示例
2018/08/20 Javascript
JS栈stack类的实现与使用方法示例
2019/01/31 Javascript
Vue匿名插槽与作用域插槽的合并和覆盖行为
2019/04/22 Javascript
vue改变循环遍历后的数据实例
2019/11/07 Javascript
编写Python脚本来获取mp3文件tag信息的教程
2015/05/04 Python
python 列表,数组,矩阵两两转换tolist()的实例
2018/04/04 Python
Python使用qrcode二维码库生成二维码方法详解
2020/02/17 Python
安装python3.7编译器后如何正确安装opnecv的方法详解
2020/06/16 Python
如何利用python发送邮件
2020/09/26 Python
安装不同版本的tensorflow与models方法实现
2021/02/20 Python
使用 HTML5 Canvas 制作水波纹效果点击图片就会触发
2014/09/15 HTML / CSS
Java面试笔试题大全
2016/11/23 面试题
2013年员工自我评价范文
2013/12/27 职场文书
红旗方阵解说词
2014/02/12 职场文书
集体婚礼策划方案
2014/02/22 职场文书
美术第二课堂活动总结
2014/07/08 职场文书
乡镇党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
神秘岛读书笔记
2015/07/01 职场文书
青年联谊会致辞
2015/07/31 职场文书
选调生挂职锻炼工作总结
2015/10/23 职场文书
2016年大学生党员承诺书
2016/03/24 职场文书
html5+实现plus.io进行拍照和图片等获取
2022/06/01 HTML / CSS
使用CSS自定义属性实现骨架屏效果
2022/06/21 HTML / CSS