javascript - 服务器应该如何实现中间件链接?
问题描述
我正在努力理解 ExpressJS 模块背后的逻辑,特别是我专注于中间件链的实现。
我的目标是了解如何实现服务器侦听请求的逻辑,并且一旦到达,将请求数据包通过一组函数传递,其中每个函数:
- 应该能够为下一个中间件修改数据包
- 应该能够发回响应,但它不应该阻止其他中间件也响应,所以在链的末端应该只有一个响应(我猜)
- 应该访问一些要调用的函数以运行链中的下一个中间件,但不需要向它传递请求和响应参数(例如,只需调用“ next() ”)
注意第1点
我想像javascript这样的语言可以使用像闭包这样的概念来传递对象,但我想以一种独立于语言的方式来理解它,并且只有在它提供了简单处理它的聪明方法时才使用javascript特性,否则我'我会像使用任何其他语言一样编写逻辑。
所以我的大问题是:
- 请求处理应该如何实现?
- 我如何允许每个中间件修改数据包?
- 如何将更新的数据包传递给下一个中间件?
- 我如何实现“下一个”函数以传递给每个中间件?
谢谢
解决方案
概括地说,这就是可以调用具有下一个函数的中间件链的方式。
function myMiddleware(req, res, next) {
// do something with req or res
next();
}
const mws = [
myMiddleware,
anotherMiddleware
];
/**
* Calls a chain of middlewares.
*
* mws is an array of middlewares
*/
function callMwChain(req, res, mws) {
if (mws.length === 0) {
// We're done here
return;
}
/**
* Take the first middleware
*/
const firstMw = mws[0];
/**
* Call it, and give it a next function that continues the chain
*/
firstMw(req, res, () => {
callMwChain(req, res, mws.slice(1));
});
}
我把它写成一个递归函数,但它也可以重写为堆栈。不过这更容易。
Express 中间件有很多额外的魔力,所以它们的实现会更加复杂,但这就是它的工作原理。
请注意,看不到事件循环。
推荐阅读
- c# - 单元测试:使用 MSTest 将复杂对象作为输入参数发送到我的测试方法
- javascript - 你如何在Javascript中反转字符串插值
- mapbox - 用 turf.js 和 mapbox 测量画线长度
- c# - 如何将 JSON 数据格式化为动态生成对象属性的 C# 对象
- python - 通过 Django Rest Framework 中的查找表进行迭代
- python - 如何在字典中添加用户?
- hadoop - Apache pig 错误 org.apache.pig.backend.hadoop.executionengine.Launcher - 错误:org.apache.avro.file.DataFileWriter$AppendWriteException:
- c++ - 引用特定函数参数
- go - 如果它们是结构的成员,何时以及如何关闭资源
- mysql - MySQL:运行存储过程从另一个存储过程中的查询获取参数