Express中间件原理详解
前言
Express和Koa是目前最主流的基于node的web开发框架,他们的开发者是同一班人马。貌似现在Koa更加流行,但是仍然有大量的项目在使用Express,所以我想通过这篇文章说说Express中间件的原理。
中间件的功能和分类
中间件的本质就是一个函数,在收到请求和返回相应的过程中做一些我们想做的事情。Express文档中对它的作用是这么描述的:
执行任何代码。
修改请求和响应对象。
终结请求-响应循环。
调用堆栈中的下一个中间件。
分类
Express文档中把他们分为了五类,但是他们的原理相同,只是用法不同:
应用级中间件
路由级中间件
错误处理中间件
内置中间件
第三方中间件
中间件的原理
首先我们看看中间件的用法:
var express = require('express')
var app = express();
app.use('/user', function (req, res, next) {
//TODO
next();
});
app.listen(8080)
接下来我们对比看一下下源码: 
与中间件有关的有三部分:
- express.js继承application.js并对外暴露接口
- application.js挂载了所有核心方法
- router文件夹处理路由逻辑
先看express.js的代码:

这部分代码中最重要的是红色方框部分,mixin是一个第三方库。可以简单理解为继承(实际上它不是继承而是混合)。
接下来我们看application.js:

这里面比较重要的是
use方法,它的作用就是把我们用app.use注册的所有中间件和路由方法交给Router类来处理。那我们再看看router文件夹类的结构:
index.js是入口文件,处理所有的路由;
Layer类,处理每一层路由中间件或者每一个子中间件;router.js中声明了
Router类,处理每一个子路由。这里面有一个子中间件的概念,对应Exprees文档中有这一句话:
另外,你还可以同时装载一系列中间件函数,从而在一个挂载点上创建一个子中间件栈。
这句话的意思是说我们可以把代码写成下面这种形式:
app.use('/user1', function fn1(req, res, next) {
// TODO
next();
}, function fn2(req, res, next) {
//TODO
next();
});
app.use('/user2', function fn3(req, res, next) {
// TODO
next();
}, function fn4(req, res, next) {
//TODO
next();
});
上面的代码给user1和user2分别创建了一个子中间件栈。这种语法的实现就是靠Layer类实现的。
画一张图来解释上面的代码:

解释一下上面的代码和图:
我们写了两个路由/user1和/user2,每个路由给了两个处理函数。对于这段代码,Express是这样处理的:
- 在index.js文件中,定义了一个
stack数组,接下来会创建两个Layer放到这个stack中。 - route.js模块会给/user1再创建一个
stack和fn1、fn2两个Layer。 - /user2同/user1
- 最后,Express会从上往下执行每个
Layer里的函数,对应到图上就是从上至下、从左至右的依次执行,顺序为fn1、fn2、fn3、fn4。
Express中间件原理详解的更多相关文章
- 淘宝JAVA中间件Diamond详解(2)-原理介绍
淘宝JAVA中间件Diamond详解(二)---原理介绍 大家好,通过第一篇的快速使用,大家已经对diamond有了一个基本的了解.本次为大家带来的是diamond核心原理的介绍,主要包括server ...
- express文件上传中间件Multer详解
express文件上传中间件Multer详解 转载自:https://www.cnblogs.com/chengdabelief/p/6580874.html Express默认并不处理HTTP请 ...
- I2C 基础原理详解
今天来学习下I2C通信~ I2C(Inter-Intergrated Circuit)指的是 IC(Intergrated Circuit)之间的(Inter) 通信方式.如上图所以有很多的周边设备都 ...
- Zigbee组网原理详解
Zigbee组网原理详解 来源:互联网 作者:佚名2015年08月13日 15:57 [导读] 组建一个完整的zigbee网状网络包括两个步骤:网络初始化.节点加入网络.其中节点加入网络又包括两个 ...
- 块级格式化上下文(block formatting context)、浮动和绝对定位的工作原理详解
CSS的可视化格式模型中具有一个非常重要地位的概念——定位方案.定位方案用以控制元素的布局,在CSS2.1中,有三种定位方案——普通流.浮动和绝对定位: 普通流:元素按照先后位置自上而下布局,inli ...
- SSL/TLS 原理详解
本文大部分整理自网络,相关文章请见文后参考. SSL/TLS作为一种互联网安全加密技术,原理较为复杂,枯燥而无味,我也是试图理解之后重新整理,尽量做到层次清晰.正文开始. 1. SSL/TLS概览 1 ...
- 锁之“轻量级锁”原理详解(Lightweight Locking)
大家知道,Java的多线程安全是基于Lock机制实现的,而Lock的性能往往不如人意. 原因是,monitorenter与monitorexit这两个控制多线程同步的bytecode原语,是JVM依赖 ...
- [转]js中几种实用的跨域方法原理详解
转自:js中几种实用的跨域方法原理详解 - 无双 - 博客园 // // 这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同 ...
- 节点地址的函数list_entry()原理详解
本节中,我们继续讲解,在linux2.4内核下,如果通过一些列函数从路径名找到目标节点. 3.3.1)接下来查看chached_lookup()的代码(namei.c) [path_walk()> ...
随机推荐
- Hdu P1394 Minimum Inversion Number | 权值线段树
题目链接 题目翻译: 约定数字序列a1,a2,...,an的反转数是满足i<j和ai>aj的数对(ai,aj)的数量. 对于给定的数字序列a1,a2,...,an,如果我们将第1到m个数字 ...
- ACM 数据读写/对拍
freopen()函数在ACM中的使用 - cfzjxz的专栏 - 博客频道 - CSDN.NET 在做acm题目的过程中,我们需要在本地机器上调试.调试过程中,如果输入数据少还可以接受,但如果输入数 ...
- hdu 5100 Chessboard (额,,,,,就叫它趣味数学题吧)
题意: 用K*1的砖块去覆盖N*N的大矩形,问最多能覆盖多少块. 详细证明:(转载自matrix67) Matrix67: The Aha Moments 趣题:用 k × 1 的矩形覆盖 n × n ...
- 记一次,因表变量导致SQL执行效率变慢
场景 最近工作中,发现某同步JOB在执行中经常抛出SQL执行超时的问题,查看日志发现每次SQL执行的时间都是线性增长的,循环执行50次以后执行时间甚至超过了5分钟 JOB执行流程分析 首先,对于JO ...
- kubernetes创建用户
创建k8s User Account 使用openssl方法创建普通用户 准备工作 1 2 3 4 mkdir /root/pki/ 将k8s ca.pem ca-key.pem 证书拷贝到此目录 ...
- Linux 服务器的基本性能及测试方法
1. 摘要 一个基于 Linux 操作系统的服务器运行的同时,也会表征出各种各样参数信息.通常来说运维人员.系统管理员会对这些数据会极为敏感,但是这些参数对于开发者来说也十分重要,尤其当程序非正常工作 ...
- @RequestAttribute与@MatrixVariable
@RequestAttribute 它只能使用在方法入参上,从request请求参数中获取对应的属性值. //路径跳转 @GetMapping("/goto") public St ...
- go的变量、常量以及判断变量的数据类型
1.定义变量 p.p1 { margin: 0; font: 12px "Helvetica Neue"; color: rgba(69, 69, 69, 1) } span.s1 ...
- C语言二分查找法
参考了C语言中折半查找法(二分法)的实现 二分查找算法(C语言实现) 先附上代码 #include<stdio.h> int BinSearch(int arr[],int len,int ...
- Spring Boot中如何自定义starter?
Spring Boot starter 我们知道Spring Boot大大简化了项目初始搭建以及开发过程,而这些都是通过Spring Boot提供的starter来完成的.品达通用权限系统就是基于Sp ...