Express 中间件原理

发布于 2022-11-24 12:47:00 字数 2883 浏览 6 评论 0

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 等关键 api)。

这里面比较重要的是 use 方法,它的作用就是把我们用 app.use 注册的所有中间件和路由方法交给 Router 类来处理。 那我们再看看 router 文件夹类的结构:

  • index.js 是入口文件,处理所有的路由;
  • layer.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 是这样处理的:

  1. 在 index.js 文件中,定义了一个 stack 数组,接下来会创建两个 Layer 放到这个 stack 中。
  2. route.js 模块会给 /user1 再创建一个 stack 和 fn1、fn2 两个 Layer
  3. /user2 同 /user1
  4. 最后,Express 会从上往下执行每个 Layer 里的函数,对应到图上就是从上至下、从左至右的依次执行,顺序为 fn1、fn2、fn3、fn4。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

列表为空,暂无数据

关于作者

故事灯

暂无简介

0 文章
0 评论
0 人气
更多

推荐作者

深爱成瘾

文章 0 评论 0

甜点

文章 0 评论 0

Ss Yy

文章 0 评论 0

dgmis009

文章 0 评论 0

花想c

文章 0 评论 0

樱花落人离去

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击“接受”或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。