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 ...
随机推荐
- 【转】Spring源码编译
原文地址: http://www.flyoung.me/2013/08/02/springcodecompile/ 参考资料: https://github.com/spring-projects/s ...
- VUE2.0实现购物车和地址选配功能学习第五节
第五节 单件商品金额计算和单选全选功能 1.vue精髓在于操作data模型来改变dom,渲染页面,而不是直接去改变dom 2.加减改变总金额功能: html:<div class="c ...
- FineUIMvc随笔 - 不能忘却的回发(__doPostBack)
声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 用户反馈 有网友在官方论坛抛出了这么一个问题,似乎对 FineUIMvc 中的浏览器端与服务器端的交互方式很有异议. 这里面的关 ...
- AIO75产品特征与优势
第一章 系统一体化 AIO7的核心流程由供应链.生产制造.财务成本及自动化办公构成,是迄今为止国内最完善的ERP.OA .HR .MES一体化产品.通过CRM(客户关系)及DRP(分销)扩充出“营销通 ...
- [C#7] 1.Tuples(元组)
1. 老版本代码 class Program { static void Main(string[] args) { var fullName = GetFullName(); Console.Wri ...
- h5标签基础 表单form
表单:收集用户信息 一. 组成: 文本框<input type="text"/> 密码框<input type="password"/> ...
- JSP中列表展示,隔行变色以及S标签的使用
1.java代码 /** * 列表展示,隔行变色以及S标签的使用 * * @return */ public String list() { List<User> list = new A ...
- 阿里宣布Atlas正式开源:带你重返App开发的田园时代
继Weex之后,阿里在移动技术领域又有开源大动作. 3月13日,手机淘宝安卓客户端容器化框架Atlas正式宣布开源(https://github.com/alibaba/atlas ).Atlas由阿 ...
- Sersync实时同步
sersync会对目录进行监控,将变化的目录或文件同步到远程服务器.sersync是递归监控的,如果有多级目录 ,都会同步到远程服务器. sersync依赖于rsync进行同步,在同步主服务器上开启s ...
- linux命令分块总结---多操作才是真理
ps:其实学习linux系统,多多联系我们现在使用的Windows系统,这样就可以事半功倍的学习: 一. 启动,关机,登入,登出相关命令 [login]: 登录 [logout] :登出 [shutd ...