koa-compose 是koa 框架的根源的根源 ,是其实现洋葱包裹型中间件的基础

以下是koa2.X 版本所以依赖的compose 版本 ,其主要核心依赖于new Promise.resolve();遍历  middleware 中间件集合,通过递归的方式来让每个prmise按步执行

注:koa每添加一个中间件实则相 ,给koa对象的middleware 中间件数组push一个新值;

//koa 对象的use方法最核心代码
use(fn) {
this.middleware.push(fn);
return this;
}

compose核心代码 【compose其实就是一个尾递归函数 ;   递归相对低效且消耗系统资源】

Compose 是一种基于 Promise 的流程控制方式,可以通过这种方式对异步流程同步化,解决之前的嵌套回调和 Promise 链式耦合。


function compose (middleware) {

  /*
* 功能: 对入参进行判断,如果入参不符合要求则直接抛出错误
*/
if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!')
for (const fn of middleware) {
if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')
} return function (context, next) {
//设置初始下标
let index = -1
//直接执行dispatch,并且从中间件数组下标0处开始执行中间件;
return dispatch(0); /**
* dispatch 函数,属于内部核心模块
*/
function dispatch (i) { //合理性判断,如果如果参数小于等于下标就说明当前中间件被多次执行则抛出异常
if (i <= index) return Promise.reject(new Error('next() called multiple times'))
index = i // 对已参数为下标的当前中间件进行局部缓存
let fn = middleware[i] // 判断是否已到达中间件数组末尾,如果到达末尾则 返回不带参数的promise
if (i === middleware.length) fn = next
if (!fn) return Promise.resolve() try {
//正常情况函数执行最终返回带有回调的promise,并且其参数就为某一个中间件
return Promise.resolve(fn(context, function next () {
return dispatch(i + 1)
}))
} catch (err) {
return Promise.reject(err)
}
}
}
}

第一次,此时第一个中间件被调用,dispatch(0),展开:

Promise.resolve(function(context, next){
//中间件一第一部分代码
await/yield next();
//中间件一第二部分代码
}());

很明显这里的next指向dispatch(1),那么就进入了第二个中间件;

第二次,此时第二个中间件被调用,dispatch(1),展开:

Promise.resolve(function(context, 中间件2){
//中间件一第一部分代码
await/yield Promise.resolve(function(context, next){
//中间件二第一部分代码
await/yield next();
//中间件二第二部分代码
}())
//中间件一第二部分代码
}());

很明显这里的next指向dispatch(2),那么就进入了第三个中间件;

第三次,此时第二个中间件被调用,dispatch(2),展开:

Promise.resolve(function(context, 中间件2){
//中间件一第一部分代码
await/yield Promise.resolve(function(context, 中间件3){
//中间件二第一部分代码
await/yield Promise(function(context){
//中间件三代码
}());
//中间件二第二部分代码
})
//中间件一第二部分代码
}());






















												

koa-compose 类库学习的更多相关文章

  1. 不学就吃亏的underscorejs类库学习示例 ——(集合篇)

    underscorejs是一个很不错的类库,我的很多项目都引用了这个类库,的确可以带来很多方便. 记得我当初学的时候,看underscorejs的api是看的一知半解的,甚至不明白api里的conte ...

  2. 新一代web框架Koa源码学习

    此文已由作者张佃鹏授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Koa 就是一种简单好用的 Web 框架.它的特点是优雅.简洁.表达力强.自由度高.本身代码只有1000多行 ...

  3. Guava:好用的java类库 学习小记

    基础功能 google guava中定义的String操作 在google guava中为字符串操作提供了很大的便利,有老牌的判断字符串是否为空字符串或者为null,用指定字符填充字符串,以及拆分合并 ...

  4. 【开源类库学习】MBProgressHUD(提示框)

    新博客: http://www.liuchendi.com MBProgressHUD是一个开源类库,实现了各种样式的提示框, 下载地址:https://github.com/jdg/MBProgre ...

  5. Java之基本类库学习

    JAVA基本类库: (一),输入相关 main(String[] args):设置输入参数 输入类:Scanner:Scanner sc=new Scanner(System.in); (二),系统相 ...

  6. JavaFX 学习笔记——jfoenix类库学习——raised风格按钮创建

    创建按钮 JFXButton jfxb = new JFXButton("hello"); jfxb.getStyleClass().add("button-raised ...

  7. 吴裕雄--天生自然java开发常用类库学习笔记:定时调度

    // 完成具体的任务操作 import java.util.TimerTask ; import java.util.Date ; import java.text.SimpleDateFormat ...

  8. 吴裕雄--天生自然java开发常用类库学习笔记:正则表达式

    public class RegexDemo01{ public static void main(String args[]){ String str = "1234567890" ...

  9. 吴裕雄--天生自然java开发常用类库学习笔记:观察者设计模式

    import java.util.* ; class House extends Observable{ // 表示房子可以被观察 private float price ;// 价钱 public ...

随机推荐

  1. 基于DNN的推荐算法总结

    1.早期的算法 深度学习在CTR预估应用的常见算法有Wide&Deep,DeepFM等. 这些方法一般的思路是:通过Embedding层,将高维离散特征转换为固定长度的连续特征,然后通过多个全 ...

  2. 2019最新黑链代码expression:隐藏链接代码

    之前有收集了一些主流的隐藏链接代码,最近又发现一种相当牛X的代码,如下: 源代码: <div style="position:absolute;left:expression(1-90 ...

  3. hyperledger fabric超级账本java sdk样例e2e代码流程分析

     一  checkConfig  Before     1.1  private static final TestConfig testConfig = TestConfig.getConfig() ...

  4. dotnet Core学习之旅(一):安装SDK

    [重要:文中所有外链不能确保永久有效] >环境 .NET Core 包含两个部分 .NET Core Runtime 和 .NET Core SDK(包含Runtime) 点击此处到达下载页面( ...

  5. Android--Fragment嵌套的问题

    项目中遇到Fragment嵌套应用的问题 子Fragment中要用getChildFragmentManager()方法获取FragmentManager,否则会出问题!

  6. 最简容器化动手小实践——再战flappybird

    <Flappy Bird>是一名越南开发者所开发的游戏,这款游戏的主要内容是帮助一只小鸟穿越水管的层层阻碍,玩家所需要的只是点击屏幕从而调整小鸟的高度.而令这款游戏与众不同的是,这款游戏的 ...

  7. 题解-CSA Round#18 Randomly Permuted Costs

    Problem CSA Round 18 题意概要:给定一个有重边有自环 \(n\) 点 \(m\) 边的有向无环图(DAG),每条边有其权值,每当你走到一个点 \(x\) 时,所有从 \(x\) 连 ...

  8. VS2015按钮方法

    protected void btnRoleMemberAdd_Click(object sender ,EventArgs e) { txtEmpID.Text=Coeno.utility.stri ...

  9. oracle 的分页、截断查询

    oracle 分页.截断查询 需求:从车管所的备案库中(oracle)取出数据,放到车综大数据平台(http方式) 现场情况:oracle中有三张表,CZRKXX(常住人口信息),ZDRYXX(重点人 ...

  10. MP4数据封装格式

    一 .MP4   https://blog.csdn.net/sdsszk/article/details/90719075 MP4   由很多个ATOM 嵌套构成,主要的ATOM包括  [ftyp] ...