zoukankan      html  css  js  c++  java
  • 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('执行完了');
    });
  • 相关阅读:
    HDU 2895 编辑距离
    AC自动机
    HDU 1707 简单模拟 Spring-outing Decision
    HDU 1710 二叉树的遍历 Binary Tree Traversals
    Codeforces Round #521 (Div. 3) E. Thematic Contests
    Codeforces Round #521 (Div. 3) D. Cutting Out
    Codeforces Round #515 (Div. 3) E. Binary Numbers AND Sum
    Codeforces Round #510 (Div. 2) B. Vitamins
    Codeforces Round #510 (Div. 2) D. Petya and Array(树状数组)
    Codeforces Round #506 (Div. 3) 题解
  • 原文地址:https://www.cnblogs.com/webjs/p/koa_middleware_simplfiy_version.html
Copyright © 2011-2022 走看看