koa-中间件流程控制
koa中间件执行流程
koa中间件的的执行顺序是洋葱模型,外层逐步向内,执行到最中间再逐步向外扩展,实现这个顺序的模型需要依赖于generator函数,它可以暂停执行将控制权交出,等到执行next再得到执行权继续执行,我们需要做的就是将generator串联起来,将后面的generator函数跟在上一层函数的yield语句之后,可以看作后面的函数是next的参数,这样我们就形成了一个串联,它的执行顺序就是我们前面所提到的洋葱模型。
koa-compose
在koa中,实现上面所说的串联函数就是利用了compose,下面是compose的大概实现(在koa中叫koa-compose):
function compose (middlewares) {
return function (next) {
var i = middlewears.length;
var next = function* () {}();
while (i--) {
next = middlewares[i].call(this, next);
<!--这一点不太好理解:首先这是个递减的过程,我们会先取到最后的一个函数
然后,next函数其实是起到一个中介的作用,将next传入后又重新更新了next
也就是在下一此的运行中next函数是带有刚刚那个最内层的函数的(最后一个)
于是再进行操作,是一个递归传入的过程,可以看这篇文章:https://cnodejs.org/topic/5723360e35af8a704195f5d5
-->
}
return next;
}
}
在koa的源码中有这样的代码:
var fn = this.experimntal
? compose_es7(this.middleware)
: co.wrap(compose(this.middleware));
我们添加中间件的时候使用app.use方法,其实这个方法只是把中间件push到一个数组,很明显,所有的中间件在数组中,那么它们之间是没有联系的,所以我们会看到上面的代码,将所有的中间件都传入了我们所说的compose中。经过compose转换的代码是下面这样
//达到了洋葱模型的效果
function *() {
yield *g1(g2(g3()))
}
co模块
上面我们看到通过使用koa-compose将中间件联系在一起(串联),可是在koa中需要调用next()方法才可以驱动函数向下执行。这时候就需要用到co模块。它可以帮我们自动管理generator的next,并根据调用返回value做出不同的响应;如果遇到另外一个generator,co会继续调用自己,这就是我们为什么需要co。
简单实现原理:
function run (gen) {
var g;
if (typeof gen.next === 'function') {
g = gen;
} else {
g = gen();
}
function next () {
var tmp = g.next();
if (tmp.done) {
return;
} else if (typeof g.next === 'function') {
run(tmp.value); // 将下一步传入run函数当中
next();
}
}
next();
}
通过递归的方式(判断是否执行结束),来驱动generator的执行。
关于co模块的补充(es6)
- co会返回一个Promise对象,因此我们可以使用then方法添加回调函数
- co真正的源码做了什么
- 检查当前代码是否为Generator函数的最后一步,如果是就返回
- 确保每一步返回的结果都是promise对象
- 使用then方法为返回值加上回调函数,然后通过onFulfilled函数再次调用next函数
- 在参数不符合要求的情况下将promise状态改为Rejected从而终止模块。
ps:理解有限,如果有误请指出!
koa-中间件流程控制的更多相关文章
- 深入探析koa之中间件流程控制篇
koa被认为是第二代web后端开发框架,相比于前代express而言,其最大的特色无疑就是解决了回调金字塔的问题,让异步的写法更加的简洁.在使用koa的过程中,其实一直比较好奇koa内部的实现机理.最 ...
- 使用yield进行异步流程控制
现状 目前我们对异步回调的解决方案有这么几种:回调,deferred/promise和事件触发.回调的方式自不必说,需要硬编码调用,而且有可能会出现复杂的嵌套关系,造成"回调黑洞" ...
- node核心:异步流程控制
Node.js的异步是整个学习Node.js过程中重中之重. 1)异步流程控制学习重点 2)Api写法:Error-first Callback 和 EventEmitter 3)中流砥柱:Promi ...
- node基础13:异步流程控制
1.流程控制 因为在node中大部分的api都是异步的,比如说读取文件,如果采用回调函数的形式,很容易造成地狱回调,代码非常不容易进行维护. 因此,为了解决这个问题,有大神写了async这个中间件.极 ...
- koa 中间件
什么是 Koa 的中间件 通俗的讲:中间件就是匹配路由之前或者匹配路由完成做的一系列的操作,我们就可以 把它叫做中间件. 在express中间件(Middleware)是一个函数,它可以访问请求对象( ...
- 在NodeJS中使用流程控制工具Async
本文介绍一款流程控制工具async,在编写接口或者编写测试用例的过程中总是会用到它. 由于nodejs是异步编程模型,有一些在同步编程中很容易做到的事情,现在却变得很麻烦.Async的流程控制就是为了 ...
- Koa - 中间件(理解中间件、实现一个验证token中间件)
前言 Koa 应用程序是一个包含一组中间件函数的对象,它是按照类似堆栈的方式组织和执行的. 当一个中间件调用 next() 则该函数暂停并将控制传递给定义的下一个中间件.当在下游没有更多的中间件执行后 ...
- Koa中间件(middleware)级联原理
前言 上次看到了koa-compose的代码,今天来说一下koa中间件的级联以及工作原理. 中间件工作原理 初始化koa实例后,我们会用use方法来加载中间件(middleware),会有一个数组来存 ...
- Koa 中间件的执行
Node.js 中请求的处理 讨论 Koa 中间件前,先看原生 Node.js 中是如何创建 server 和处理请求的. node_server.js const http = require(&q ...
随机推荐
- ajax跨域问题及解决
overview ajax是一种创建交互式网页应用的网页开发技术,是一种用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换.而ajax的跨域问题则是请求了其他项目的接口地址,当协议.子域名 ...
- InstallShield打包
使用2010部分汉化版(2010之后找不到更新的破解版本),主要用于打包桌面应用程序. 主要步骤: 1.3种主要的工程类型: Basic MSI,安装脚本不易使用. InstallScript,无法加 ...
- Java源码ExtJS 5 SpringMVC 4Hibernate 4通用后台管理开发框架
需要源码,请加QQ:858-048-581 一.特色1.采用Spring MVC的静态加载缓存功能,在首页将Javascript文件.CSS文件和图片等静态资源文件加载进来放进内存,极大提高ExtJS ...
- 2017-3-5 C#基础 函数
函数/方法:非常抽象独立完成某项功能的一个个体 函数的作用: 提高代码的重用性提高功能开发的效率提高程序代码的可维护性 函数分为: 固定功能函数高度抽象函数 函数四要素:输入,输出,函数体,函数名 p ...
- 监听器如何获取Spring配置文件(加载生成Spring容器)
Spring容器是生成Bean的工厂,我们在做项目的时候,会用到监听器去获取spring的配置文件,然后从中拿出我们需要的bean出来,比如做网站首页,假设商品的后台业务逻辑都做好了,我们需要创建一个 ...
- Lucene实战之初体验
前言 最早做非结构化数据搜索时用的还是lucene.net,一直说在学习java的同时把lucene这块搞一搞,这拖了2年多了,终于开始搞这块了. 开发环境 idea2016.lucene6.0.jd ...
- Java容器源码解析之——ArrayList
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess ...
- 摆脱printf的噩梦
众所周知,printf是一个方便.直观.易写.变长参数的打印函数,但它有一个致命的缺陷,如下的语句将导致程序出现严重的运行时错误: printf("%s", 1); 然后程序中断, ...
- 基于Spring Cloud和Netflix OSS构建微服务,Part 2
在上一篇文章中,我们已使用Spring Cloud和Netflix OSS中的核心组件,如Eureka.Ribbon和Zuul,部分实现了操作模型(operations model),允许单独部署的微 ...
- TextView字体大小及颜色设置
TextView设置文字大小及颜色: 1.1)通过xml配置 <TextView android:layout_width="match_parent" a ...