koa2 总体流程原理浅析(一) 之 koa 启动服务器解析

启动流程

koa 主要的启动流程就是下面的 4 步:引入 koa 包 => 实例化 koa => 编写中间件 => 监听服务器
const koa = require('koa');

const app = new koa();

app.use(function 1(){})
app.use(function 2(){})
app.use(function 3(){})

app.listen(port,function(){})

引入 koa 包

引入 koa 包其实就是引入的一个 继承于 node 原生的 events 类的 Application 类
module.exports = class Application extends Emitter {
  constructor() {
    super();

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

  listen(...args) {}
  
  toJSON() {}

  inspect() {}

  use(fn) {}

  callback() {}

  handleRequest(ctx, fnMiddleware) {}

  createContext(req, res) {}

  onerror(err) {}
};
其中就包含了 listen 、use 等原型方法

实例化 koa

执行 constructor ,将 ctx、response、request 等对象封装在 koa 实例中

编写中间件

use(fn) {
    if (typeof fn !== 'function') throw new TypeError('middleware must be a function!');
    if (isGeneratorFunction(fn)) {
      deprecate('Support for generators will be removed in v3. ' +
                'See the documentation for examples of how to convert old middleware ' +
                'https://github.com/koajs/koa/blob/master/docs/migration.md');
      fn = convert(fn);
    }
    debug('use %s', fn._name || fn.name || '-');
    this.middleware.push(fn);
    return this;
}
  • 首先判断 fn 的类型,不是方法直接抛错
  • 是生成器函数的话用 co 封装
  • 是 async 函数的话直接放入中间件数组中
  • 测试了一下,如果是普通函数的话,1.X 版本会报错,2.X 版本可以执行,但是由于没有 next,只能执行第一个
use 的作用就是把中间件函数依次放入 ctx.middleware 中,等待请求到来的时候顺序调用

监听服务器

listen(...args) {
    debug('listen');
    const server = http.createServer(this.callback()); // 这里注册了 node 的 request 事件
    return server.listen(...args);
  }
koa 的监听主要有两个封装:
  1. 封装原生的 node sever 监听
  2. 封装 koa.callback(),并且为这个服务器设置了 node 的 request 事件,这意味着当每一个请求到来时就会执行 koa.callback() 方法,这是极为关键的一步,是 koa 中间件原理的基础

下回分解

下一章我们会讲解中间件的原理

END

 
 

koa

相关推荐