koa中间件实现分析

最近团队内部做了一个web app,用koa做服务端,一直对他中间件实现很感兴趣,对他的源码研究之后,写了一份简化版本的中间件实现。代码除了用到ES6的Generator和Promise,没有用到其他三方库,总共不到一百行,希望能帮助大家理解!

‘use strict‘;
var middleware = [];

//向数据库请求数据
var getDataPromise = new Promise(function(resolve,reject){
   setTimeout(function(){
      resolve({
         data:‘这就是数据‘
      });
   },1500)
});

/**
 * session中间件
  * @param next
 */
function* session(next){
   console.log(1);
   yield next;
   console.log(2);
}
middleware.push(session);

/**
 * logger中间件
 */

function* logger(next){
   console.log(3);
   yield next;
   console.log(4);
}
middleware.push(logger);

/**
 * response中间件
 */
function* response(){
   console.log(5);
   console.log(‘请求数据库数据...‘);
   let data = yield getDataPromise;
   console.log(data);
   console.log(6);
}
middleware.push(response);

/**
 * 将中间件的遍历器函数转化为遍历器对象,并且将每一个遍历器对象指定为下一个遍历器对象的参数
 * @param next
 * @returns {*}
 */
function* toGeneratorObject(next){
   if (!next) next = function*(){};

   var i = middleware.length;

   while (i--) {
      next = middleware[i].call(this, next);
   }

   return yield *next;
}

//第一个中间件的遍历器对象
var firstMiddleWareGenerator = toGeneratorObject();

/**
 * 将中间件的遍历器对象包装成一个Promise
 * @param gen
 * @returns {Promise}
 */
function  wrapPromise(gen){
  return new Promise(function(resolve,reject){
     function onFullField (res){
        var ret = gen.next(res);
        next(ret);
     }
     onFullField();
     function next(ret){
        var value = null;
        if(ret.done){
           resolve(ret.value);
           return;
        }
        //假如是promise,不做任何处理
        if(typeof ret.value.then == ‘function‘){
           value = ret.value;
        }else { //假如不是,就包装成promise实例
           value = wrapPromise(ret.value);
        }
        value.then(onFullField);
     }
   });
}
wrapPromise(firstMiddleWareGenerator).then(function(){
   console.log(‘执行完了‘);
});
时间: 2024-10-08 08:56:25

koa中间件实现分析的相关文章

koa中间件分析

转载请注明: TheViper http://www.cnblogs.com/TheViper  另外可以参考http://purplebamboo.github.io/2014/05/24/koa-source-analytics-3/,作者用简单的方式造了一个山寨koa. koa是什么? koa是从2013年11月开始发布,更新的.和express相比,koa太年轻了.但它(用文档上的话说)通过组合不同的 generator,可以免除重复繁琐的回调函数嵌套,并极大地提升常用错误处理效率.Ko

KOA中间件实现原理

1 //基本原理 2 var empty=(function *(){})(); 3 //中间件3 4 var mid2=function *(){ 5 console.log("2:before yield"); 6 yield empty; 7 console.log("2:after yield"); 8 } 9 //中间件2 10 var mid1=function *(){ 11 console.log("1:before yield"

Koa - 中间件

前言 Koa 应用程序是一个包含一组中间件函数的对象,它是按照类似堆栈的方式组织和执行的. 当一个中间件调用 next() 则该函数暂停并将控制传递给定义的下一个中间件.当在下游没有更多的中间件执行后,堆栈将展开并且每个中间件恢复执行其上游行为. 以上两句话,是我在官方文档中找到其对 Koa 中间件的描述. 在Koa中,中间件是一个很有意思的设计,它处于request和response中间,被用来实现某种功能.像上篇文章所使用的 koa-router .koa-bodyparser 等都是中间件

Koa中间件(middleware)级联原理

前言 上次看到了koa-compose的代码,今天来说一下koa中间件的级联以及工作原理. 中间件工作原理 初始化koa实例后,我们会用use方法来加载中间件(middleware),会有一个数组来存储中间件,use调用顺序会决定中间件的执行顺序. 每个中间件都是一个函数(不是函数将报错),接收两个参数,第一个是ctx上下文对象,另一个是next函数(由koa-compose定义) 在建立好http服务器后,会调用koa-compose模块对middleware中间件数组进行处理.具体代码这里就

分布式缓存中间件优缺点分析(redis、memcache、ehcache)

分布式缓存中间件优缺点分析(redis.memcache.ehcache) 1. redis 优点: 1. 丰富的数据结构,支持字符串(strings).散列(hashes).列表(lists).集合 (sets).有序集合(sorted sets) 2. 主从同步,故障转移 集群 3. 持久化 缺点: 1. 单核,单线程,所以在存储海量数据的时候会极大的影响系统性能 2. memcache     优点: 1. 简单的key-value存储,memcache的key-value只支持Strin

傻瓜式解读koa中间件处理模块koa-compose

最近需要单独使用到koa-compose这个模块,虽然使用koa的时候大致知道中间件的执行流程,但是没仔细研究过源码用起来还是不放心(主要是这个模块代码少,多的话也没兴趣去研究了). koa-compose看起来代码少,但是确实绕.闭包,递归,Promise...看了一遍脑子里绕不清楚.看了网上几篇解读文章,都是针对单行代码做解释,还是绕不清楚.最后只好采取一种傻瓜的方式: koa-compose去掉一些注释,类型校验后,源码如下: function compose (middleware) {

koa源码分析

最近项目要使用koa,所以提前学习一下,顺便看了koa框架的源码. 注:源码是koa2.x koa的源码很简洁,关键代码只有4个文件,当然还包括一些依赖npm包 const Koa = require('koa'); const app = new Koa(); app.use(async (ctx, next) => { await next(); ctx.type = 'text/html'; ctx.body = '<h1>Hello, koa2!</h2>'; });

nextjs作为koa中间件的使用

react客户端渲染的缺点:首屏速度慢,对SEO不友好 浏览器请求步骤                                                        客户端跳转 1. 浏览器发起请求 /index                                           1.  点击按钮 2. koa接受请求,并且调用nextjs                                 2. 异步加载组件的js 3. nextjs开始渲染   

koa2入门--03.koa中间件以及中间件执行流程

//中间件:先访问app的中间件的执行顺序类似嵌套函数,由外到内,再由内到外 //应用级中间件 const koa = require('koa'); var router = require('koa-router')(); var app = new koa(); //匹配任意路由之前打印日期 app.use(async (ctx,next)=>{ console.log(new Date()); await next(); }); router.get('/',async (ctx)=>