【摘要】 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);

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

作者:大史不说话

【nodejs原理&源码赏析(2)】KOA中间件的基本运作原理的更多相关文章

  1. 【nodejs原理&源码赏析(5)】net模块与通讯的实现

    [摘要] Node.js net模块的原理及使用 示例代码托管在:http://www.github.com/dashnowords/blogs 一. net模块简介 net模块是nodejs通讯功能 ...

  2. 【nodejs原理&源码赏析(5)】net模块与通讯的实现

    目录 一. net模块简介 二. Client-Server的通讯 2.1 server的建立 2.2 Socket的建立 三. IPC通讯 四. 撸一个简易的cluster通讯模型 示例代码托管在: ...

  3. 【nodejs原理&源码赏析(4)】深度剖析cluster模块源码与node.js多进程(上)

    [摘要] 集群管理模块cluster浅析 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 概述 cluster模块是node.js中用于实现和管理 ...

  4. 【nodejs原理&源码赏析(4)】深度剖析cluster模块源码与node.js多进程(上)

    目录 一. 概述 二. 线程与进程 三. cluster模块源码解析 3.1 起步 3.2 入口 3.3 主进程模块master.js 3.4 子进程模块child.js 四. 小结 示例代码托管在: ...

  5. 【nodejs原理&源码赏析(3)】欣赏手术级的原型链加工艺术

    目录 一. 概述 二. 原型链基础知识 三. Worker类的原型链加工 四. 实例的生成 五. 最后一个问题 六. 一些心得 示例代码托管在:http://www.github.com/dashno ...

  6. 【nodejs原理&源码赏析(6)】深度剖析cluster模块源码与node.js多进程(下)

    [摘要] cluster模块详解 示例代码托管在:http://www.github.com/dashnowords/blogs 阅读本章需要先阅读本系列前两章内容预热一下. 一. 引言 前两篇博文中 ...

  7. 【nodejs原理&源码赏析(3)】欣赏手术级的原型链加工艺术

    [摘要] 学习经典代码中的prototype加工 示例代码托管在:http://www.github.com/dashnowords/blogs 好的代码都差不多,烂的代码却各有各的烂法. 一. 概述 ...

  8. 【nodejs原理&源码赏析(6)】深度剖析cluster模块源码与node.js多进程(下)

    目录 一. 引言 二.server.listen方法 三.cluster._getServer( )方法 四.跨进程通讯工具方法Utils 五.act:queryServer消息 六.轮询调度Roun ...

  9. KOA中间件的基本运作原理

    示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 华为云社区地址:[你要的前端打怪升级指南] 在中 ...

随机推荐

  1. CSPS_108

    二逼出题人写错T1题面&&写伪T3std祭

  2. 通俗易懂了解Vue组件的生命周期

    1.前言 在使用vue2.0进行日常开发中,我们总有这样的需求,我就想在页面刚一加载出这个表格组件时就发送请求去后台拉取数据,亦或者我想在组件加载前显示个loading图,当组件加载出来就让这个loa ...

  3. UiPath之如何打印PDF

    各位小伙伴,大家好,今天写一点基础知识,如何在UiPath中打印PDF. ---小U的QQ群(714733686):小U的订阅号[UiPath8888]--- 当然,我们最希望的就是有一个Activi ...

  4. L0、L1、L2范数正则化

    一.范数的概念 向量范数是定义了向量的类似于长度的性质,满足正定,齐次,三角不等式的关系就称作范数. 一般分为L0.L1.L2与L_infinity范数. 二.范数正则化背景 1. 监督机器学习问题无 ...

  5. css3 input placeholder颜色修改方法

    css3 input placeholder颜色修改方法<pre> input::-webkit-input-placeholder { /* placeholder颜色 */ color ...

  6. day5-基本数据类型总结

    一.数字int(..)二.字符串replace/find/join/strip/startswith/split/upper/lower/format tempalte = "i am {n ...

  7. 可保图片不变形的object-fit

    Object-fit 我们有时候浏览一些网站的时候,偶尔会遇到这种情况:  明显它喵的形变了,尤其是这种这么业余的失误,还是出现在一个专门做图片的网站上. 产生这种现象的原因是:图片写了固定的宽高,这 ...

  8. H5+app -- 关于ajax提交问题

    1.前阵子在做系统的h5+ app为满足手机端也能进行业务操作,例如:提货,扫描入库之类的.所以就要将做接口,从手机端调用后台系统的方法. 2.例如这样的请求格式,但是呢,每次请求它都直接跳到erro ...

  9. 手把手教你实现热更新功能,带你了解 Arthas 热更新背后的原理

    文章来源:https://studyidea.cn/java-hotswap 一.前言 一天下午正在摸鱼的时候,测试小姐姐走了过来求助,说是需要改动测试环境 mock 应用.但是这个应用一时半会又找不 ...

  10. JavaScript 运行原理

    i{margin-right:4px;margin-top:-0.2em}.like_comment_tips .weui-icon-success{background:transparent ur ...