Koa 框架學習

來自專欄 Node.js 學習

const Koa = require(koa);const app = new Koa();const port = 3000;app.use(ctx => { ctx.body = Hello Koa});app.listen(port);

以上為koa 創建一個server

現在我們分析源碼:

const app = new Koa()

做了那些事情:首先構造函數

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);}

聲明為中間件和context request response

該類Application繼承於Emitter

module.exports = class Application extends Emitter

listen 函數

listen(...args) { debug(listen); const server = http.createServer(this.callback()); return server.listen(...args); }

通過這張圖 我們可以發現app裡面掛載了context request 和response

中間件:

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; }

用一個數組middleware 將當前的fn push進去

我們需要剖析一下:listen 裡面的this.callback();

callback() { const fn = compose(this.middleware); if (!this.listenerCount(error)) this.on(error, this.onerror); const handleRequest = (req, res) => { const ctx = this.createContext(req, res); return this.handleRequest(ctx, fn); }; return handleRequest; }

先將中間件組合為一個嵌套函數供返回的函數執行時候調用。

this.createContext 根據req 和res 封裝中間件所需要的ctx。

我們再看this.createContext如何定義:

createContext(req, res) { const context = Object.create(this.context); const request = context.request = Object.create(this.request); const response = context.response = Object.create(this.response); context.app = request.app = response.app = this; context.req = request.req = response.req = req; context.res = request.res = response.res = res; request.ctx = response.ctx = context; request.response = response; response.request = request; context.originalUrl = request.originalUrl = req.url; context.state = {}; return context; }

我們看這個函數創建了簡單的對象,並且將他們的原型指定為我們app中對應的對象。

推薦閱讀:

相关文章