前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >KOA中间件的基本运作原理

KOA中间件的基本运作原理

作者头像
大史不说话
发布2019-03-11 10:58:21
8620
发布2019-03-11 10:58:21
举报
文章被收录于专栏:大史住在大前端

示例代码托管在: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);

二. 核心类的定义

代码语言:javascript
复制
/*
* 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方法添加中间件

代码语言:javascript
复制
//添加回调函数
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');
});

四. 中间件实例

代码语言:javascript
复制
//初始化
let middleware = new MiddleWare();

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

middleware.start = middleware.compose();

五. 查看运行结果

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

六. 在服务器端运行

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

代码语言:javascript
复制
//启动http服务
http.createServer(function(req, res){
    console.log(req.url);
    let info = {};
    middleware.start(info);
    res.end(JSON.stringify(info));
}).listen(9527);

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-02-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. API层
  • 二. 核心类的定义
  • 三. 使用use方法添加中间件
  • 四. 中间件实例
  • 五. 查看运行结果
  • 六. 在服务器端运行
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档