专栏首页大史住在大前端KOA中间件的基本运作原理

KOA中间件的基本运作原理

示例代码托管在:http://www.github.com/dashnowords/blogs

在中间件系统的实现上,KOA中间件通过async/await来在不同中间件之间交换控制权,工作机制和结构非常相似,建议结合《express中间件系统的基本实现》对比学习,两个框架所基于的语法特性有区别(express使用ES5的回调风格语法,KOA使用ES7的扁平式异步async/await风格语法),但在框架基本原理上是很类似的,只是中间件写法和遍历机制稍有不同。

一. API层

  • 初始化方法 let middleware = new MiddleWare();
  • 添加中间件函数的方法 //Fn为被添加的中间件,KOA中间件为async函数 middleware.use(Fn);
  • 预处理中间件栈 //将存储于数组中的各个中间件组合为按照“先进后出”原则执行的中间件系统。 middleware.start = middleware.compose();
  • 启动中间件队列 middleware.start(ctx);

二. 核心类的定义

/*
* KOA中间件框架的基本实现
*/

class MiddleWare {
    constructor(){
        this.queue = []
    }

    //添加中间件函数
    use(fn){
       this.queue.push(fn);
    }

    //合并中间件处理流,是一个高阶函数,调用一次后会生成真正需要的函数。
    compose(){
        return function (ctx, next) {
           let _this= this;
           let index = -1;
           return dispatch(0);
           
           /**
            * KOA中间件的工作的步进函数
            */
           function dispatch(i) {
             index = i;
             //依次取用数组中添加的中间件函数
             let fn = i === _this.queue.length ? next : _this.queue[i];
             if(!fn){
               return Promise.resolve();
             }
             
             try{
                 /*
                 *中间件函数的形式为 async fn(ctx, next),可以看到此处透传了ctx的引用,
                 *同时next是一个延迟执行中间件队列中下一个中间件的函数,也就是说如果在前
                 *一个中间件的函数体中调用 await next(),就会启动下一个中间件,实际执行
                 *的函数是dispatch(i+1)。
                 */
                 return Promise.resolve(fn(ctx,()=>{
                   return dispatch(i+1);
                 }));
             }catch(err){
                 return Promise.reject(err);
             }
           }
        }
    }
}

三. 使用use方法添加中间件

//添加回调函数
middleware.use(async function(ctx, next){
  console.log('step 001');
  ctx.info = 'go through middleware1';
  await next();
  console.log('step 006');
});

middleware.use(async function(ctx, next){
  console.log('step 002');
  await next();
  console.log('step 005');
});

middleware.use(async function(ctx, next){
  console.log('step 003');
  await next();
  console.log('step 004');
});

四. 中间件实例

//初始化
let middleware = new MiddleWare();

/*
...此处为添加中间件的代码
*/

middleware.start = middleware.compose();

五. 查看运行结果

可以看到有错误发生和正常响应时的不同结果:

六. 在服务器端运行

node起一个web服务器那真是太随意了~

//启动http服务
http.createServer(function(req, res){
    console.log(req.url);
    let info = {};
    middleware.start(info);
    res.end(JSON.stringify(info));
}).listen(9527);

看一下效果(访问服务器时自定义消息就可以传至前台了):

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • express中间件系统的基本实现

    一直觉得express的中间件系统这种流式处理非常形象,就好像加工流水线一样,每个环节都在针对同一个产品的不同部分完成自己的工作,最后得到一个成品。今天就来实现...

    大史不说话
  • 【带着canvas去流浪(12)】用Three.js制作简易的MARVEL片头动画(上)

    通读完上一篇博文中提及的教程,觉得应该搞个大作业巩固一下所学的知识,想起刚上映的漫威宇宙第三阶段收官之作《蜘蛛侠·英雄远征》,于是决定仿一个MARVEL的片头动...

    大史不说话
  • 【nodejs原理&源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick

    事件循环是Node.js能够实现非阻塞I/O的基础,尽管JavaScript应用是单线程运行的,但是它可以将操作向下传递到系统内核去执行。

    大史不说话
  • 浅谈Laravel中的三种中间件的作用

    在之前一直简单的认为中间件就是往middleware里添加中间件即可。现在才知道中间件有三种类型,分别为:middleware middlewareGroup

    砸漏
  • mysql分布式数据库中间件对比mysql分布式数据库中间件对比

    mysql分布式数据库中间件对比 目前数据库中间件有很多,基本这些中间件在下都有了解和使用,各种中间件优缺点及使用场景也都有些心的。所以总结一个关于中间件比较的...

    Albert陈凯
  • 爬虫框架scrapy之中间件

    中间件是Scrapy里面的一个核心概念。使用中间件可以在爬虫的请求发起之前或者请求返回之后对数据进行定制化修改,从而开发出适应不同情况的爬虫。

    菲宇
  • What?Tomcat 竟然也算中间件?

    本来今天就该讲 MyCat 了,但是我发现还有一个概念值得和大家聊一下,那就是 Java 中间件!

    江南一点雨
  • Laravel 三种中间件作用讲解

    昨天在开发过程中,需要使用到中间件的技术,之前都只是简单的认为要增加中间件就往middleware里添加中间件即可。本着周末的时间,就仔细研究了下 $middl...

    双面人
  • 系统架构师论文-论中间件在SIM卡应用开发中的作用

    我曾于近期参与过一个基于SIM卡应用的开发项目,并在项目中担任系统分析的工作。在分析过程中,我们依据面向対象方法対系统进行了划分,其中许多的模块已有成熟的中间件...

    cwl_java
  • 谈谈中间件开发,给想从事中间件开发的同学

    随着国内软件行业的发展,国内互联网公司规模越来越大,业务越来越复杂,随之使用大量的中间件来提高后台服务性能。由此产生了中间件开发和维护人员。

    芋道源码

扫码关注云+社区

领取腾讯云代金券