koa-源码分析

Koa源码分析

前两篇已经了解了yield和generator的相关概念,这篇文章继续分析Koa的源码,
Koa的用法,这里就不在列举了。我以为Koa主要功能主要是下面几个方面

1).    提供了中间件机制
2).    封装了request/response,context对象
3).    使用了yield,提供了便利的流程控制,使异步编程更优雅
4).    便捷的异常处理,使用try catch就能够捕获程序中的异常,不须要考虑同步或者异步的问题

简单的例子

import koa from 'koa';
const app = koa();
app.experimental = true;
app.proxy = true;//当 app.proxy 设置为 true 时,支持 X-Forwarded-Host
//添加一个中间件
app.use(function*(next) {前端

console.log('start');
     yield *next;
     console.log('end');
 })

app.listen(port);编程

koa会提供不少中间件,好比koa-router,koa-session,koa-bodyparse,koa-server等数组

koa源码分析之Application

var app = Application.prototype;
module.exports = Application;session

//函数的入口部分app

function Application() {dom

if (!(this instanceof Application)) return new Application;
      this.env = process.env.NODE_ENV || 'development';
      this.subdomainOffset = 2;
      this.middleware = [];
      this.proxy = false;
      this.context = Object.create(context);
      this.request = Object.create(request);
      this.response = Object.create(response);
    }

listen真正的建立了一个http serverkoa

app.listen = function(){异步

var server = http.createServer(this.callback());
      return server.listen.apply(server, arguments);
  };

中间件use方法, fn必须是一个generator function, 能够经过'GeneratorFunction' == fn.constructor.name异步编程

app.use = function(fn){
      if (!this.experimental) {
        // so we have to make sure that `fn` is a generator function
        assert(fn && 'GeneratorFunction' == fn.constructor.name, 'app.use() requires a generator function');
      }
      this.middleware.push(fn);
      return this;
  };

重要函数来啦,这里只是分析this.experimental = false的状况函数

app.callback = function(){
      var fn = this.experimental
        ? compose_es7(this.middleware)
        : co.wrap(compose(this.middleware));
        
        //co是使用的tj的co模块,这里先分析compose的函数用法
        //compose 函数是将this.middleware数组的函数进行一个简单的处理,保证每一个函数都有后一个函数的引用,具体代码看下面的分析
        //co.wrap能够将一个generation function 进行转换,使fn可以自动运行
        
      var self = this;
    
      if (!this.listeners('error').length) this.on('error', this.onerror);
    
      return function(req, res){
        res.statusCode = 404;
        var ctx = self.createContext(req, res);
        onFinished(res, ctx.onerror);
        //这里执行中间件函数,而后将处理的结果都挂在ctx上,最后respond函数输出到前端,注意catch函数进行错误逻辑处理
        fn.call(ctx).then(function () {
          respond.call(ctx);
        }).catch(ctx.onerror);
      }
};

compose 代码分析, compse是将middleware里面的middleware都有下一个函数的引用

function compose(middleware){
      return function *(next){
        if (!next) next = noop();
    
        var i = middleware.length;
    
        while (i--) {
          next = middleware[i].call(this, next);
        }
    
        return yield *next;
      }
    }

至此,koa的源码已经分析完毕了

相关文章
相关标签/搜索