koa2 總體流程原理淺析(一) 之 koa 啟動伺服器解析

Elias發表於2019-02-16

啟動流程

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

 
 

相關文章