中间件的实现原理
来源:互联网 发布:安卓网络配置文件路径 编辑:程序博客网 时间:2024/06/05 14:09
用过express的同学都知道,一个HTTP请求的完成就是经过若干中间件完成的,中间件是一个可访问请求对象(req
)和响应对象(res
)的函数,在 Express 应用的请求-响应循环里,下一个内联的中间件通常用变量 next
表示。
那么现在我先上一道我面试中遇到的一道题,考的就是中间件的一个实现思路。当然如果你知道express,会更好地帮助你理解。
function fun1(ctx, next) { ctx.count++; console.log(ctx.count); next(); } function fun2(ctx, next) { ctx.count++; console.log(ctx.count); next(); } function fun3(ctx, next) { ctx.count++; console.log(ctx.count); next(); } compose([fun1, fun2, fun3])({count: 1});
这道题的是让你实现一个compose,使得compose([fun1, fun2, fun3])({count: 1})调用后,使得fun1 fun2 fun3依次执行,比如在fun1里面当
next被调用时,就会把控制权交给下一个中间件函数,fun1的下一个中间件函数fun2就会被执行,{count:1}是传入的context,中间件函数就是
依次对context对象进行处理。
我的compose实现思路很简单,如下
function compose(arr){ index = 0; len = arr.length; return function (ctx) { function next() { index++; if(index >= len) return; arr[index](ctx, next); } arr[index](ctx, next); } }
这样输出的结果是 2 3 4,和预期相符
下面我们来验证一个这个解法对不对。
测试一:如果在某个中间函数体中,用户没有调用next,则不会继续调用下个中间件函数。
function fun1(ctx, next) { ctx.count++; console.log(ctx.count); next(); } function fun2(ctx, next) { ctx.count++; console.log(ctx.count);// next(); } function fun3(ctx, next) { ctx.count++; console.log(ctx.count); next(); } compose([fun1, fun2, fun3])({count: 1});如上在fun2中没用调用next ,则输出为2 3,和预期相符
测试二:如果next的调用在异步环境里面,则下一个中间件函数必须等上一个中间件函数的next真正被调用(即使是异步)时才会执行。
function fun1(ctx, next) { ctx.count++; console.log(ctx.count); next(); } function fun2(ctx, next) { ctx.count++; console.log(ctx.count); setTimeout(function () { next(); },1000); } function fun3(ctx, next) { ctx.count++; console.log(ctx.count); next(); } compose([fun1, fun2, fun3])({count: 1});如上,在fun2中1s后才调用next,输出为 2 3 然后一秒后输出4 ,符合预期。
当然这是一个最简单的中间件实现思路,在express中间件中远比这复杂,但是这可以考察你解决问题的思路。
阅读全文
0 0
- 中间件的实现原理
- Laravel中间件实现原理
- Laravel中间件实现原理
- 浅谈redux 中间件的原理
- 解读 Redux 中间件的原理
- 模拟 co.js 的实现原理 (koa中间件的实现)
- 中间件原理
- Xianfeng轻量级Java中间件平台:基于RBAC模型实现权限控制的原理
- ActiveMQ消息中间件 原理详解 &&附demo实现、以及与springboot集成的demo
- 简单简陋的中间件开发原理。
- 数据库shard中间件对比,以及sharding-jdbc 实现原理分析
- 基于ATL的智能卡中间件的实现
- Web服务数据库访问中间件的实现
- Web服务数据库访问中间件的实现
- 前营中间件(4) - 客户端的实现
- 消息中间件原理
- todo 中间件原理
- 分布式消息中间件rocketmq的原理与实践
- 利用history对象实现地址栏更新,页面局部刷新
- java 读取 txt文件 特定行
- 关于linux删除文件夹命令方法
- maven私服的搭建
- INFO [Timer-282] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading.....
- 中间件的实现原理
- Java面向对象-String类作业一字符串转数组
- Nginx为什么比Apache Httpd高效:原理篇
- Python3 (入门3) 函数
- 非IE内核浏览器支持Active X控件
- codeforces 420-C. Okabe and Boxes
- 其他协议
- Oracle数据库(数据字典、表空间、表的创建、视图)
- JS跳转页面