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实用示例 缩址还原
Dec 28 NodeJs
nodejs中exports与module.exports的区别详细介绍
Jan 14 NodeJs
nodejs之请求路由概述
Jul 05 NodeJs
nodeJS代码实现计算交社保是否合适
Mar 09 NodeJs
Nodejs进阶:如何将图片转成datauri嵌入到网页中去实例
Nov 21 NodeJs
Nodejs 发送Post请求功能(发短信验证码例子)
Feb 09 NodeJs
nodejs+express实现文件上传下载管理网站
Mar 15 NodeJs
nodejs 终端打印进度条实例代码
Apr 22 NodeJs
Nodejs中crypto模块的安全知识讲解
Jan 03 NodeJs
Nodejs 发布自己的npm包并制作成命令行工具的实例讲解
May 15 NodeJs
详解利用nodejs对本地json文件进行增删改查
Sep 20 NodeJs
nodejs中的异步编程知识点详解
Jan 17 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
多人战的战术与战略
2020/03/04 星际争霸
PHP下escape解码函数的实现方法
2010/08/08 PHP
php检查字符串中是否包含7位GSM字符的方法
2015/03/17 PHP
crontab无法执行php的解决方法
2016/01/25 PHP
PHP7.1方括号数组符号多值复制及指定键值赋值用法分析
2016/09/26 PHP
JQuery 学习笔记 选择器之二
2009/07/23 Javascript
AeroWindow 基于JQuery的弹出窗口插件
2011/06/27 Javascript
WordPress 单页面上一页下一页的实现方法【附代码】
2016/03/10 Javascript
使用React实现轮播效果组件示例代码
2016/09/05 Javascript
微信小程序加载更多 点击查看更多
2016/11/29 Javascript
ThinkPHP+jquery实现“加载更多”功能代码
2017/03/11 Javascript
nodejs服务搭建教程 nodejs访问本地站点文件
2017/04/07 NodeJs
页面间固定参数,通过cookie传值的实现方法
2017/05/31 Javascript
关于JS与jQuery中的文档加载问题
2017/08/22 jQuery
Vue 中使用vue2-highcharts实现top功能的示例
2018/03/05 Javascript
vue自定义指令实现方法详解
2019/02/11 Javascript
详解基于iview-ui的导航栏路径(面包屑)配置
2019/02/22 Javascript
VUE引入第三方js包及调用方法讲解
2019/03/01 Javascript
Python 时间处理datetime实例
2008/09/06 Python
Python 开发Activex组件方法
2009/11/08 Python
python应用程序在windows下不出现cmd窗口的办法
2014/05/29 Python
Python for Informatics 第11章 正则表达式(一)
2016/04/21 Python
Python中的探索性数据分析(功能式)
2017/12/22 Python
深入浅析Python中list的复制及深拷贝与浅拷贝
2018/09/03 Python
Python如何实现转换URL详解
2019/07/02 Python
分享一个pycharm专业版安装的永久使用方法
2019/09/24 Python
利用HTML5的新特点实现图片文件异步上传
2014/05/29 HTML / CSS
大学生年度自我鉴定
2013/10/31 职场文书
同事吵架检讨书
2014/02/05 职场文书
银行开业庆典方案
2014/02/06 职场文书
三严三实对照检查材料思想汇报
2014/09/28 职场文书
共产党员批评与自我批评
2014/10/15 职场文书
高一作文之暖冬
2019/11/09 职场文书
python使用glob检索文件的操作
2021/05/20 Python
Python利用capstone实现反汇编
2022/04/06 Python
Docker与K8s关系介绍不会Docker也可以使用K8s
2022/06/25 Servers