首頁>技術>

目標

本文主要通過一個簡單的例子來解釋koa的內部原理。

koa的一個簡單例子

圖1是Koa的一個簡單例子,下文會對這個例子的每行程式碼背後的邏輯做詳細分析。

koa內部檔案組成

圖2 Koa程式碼檔案

圖3 檔案和具體類

application.js中包含了Application類和一些輔助方法context.js主要作用是承載上下資訊,並封裝了處理上下文資訊的操作request.js中封裝了處理請求資訊的基本操作response.js中封裝了處理響應資訊的基本操作

koa內部

在圖1的例子中,執行const app = new koa()時,實際上構造了一個Application例項,圖4為Application構造方法,構造方法中建立了Context、Request、Response等類的執行例項。關於Context、Response、Request類及方法介紹請參考

https://koajs.com/

下文約定request代指Request類例項,response代指Response類例項,context代指Context類例項。

圖4 Application構造方法

圖1的例子中呼叫app.listen(3000)方法監聽3000埠進來的http請求,listen方法內部建立了一個http.Server物件,並呼叫http.Server的listen方法。具體程式碼如圖5。

圖5中this.callback方法的原始碼如下圖6中所示

圖6 callback

callback方法返回一個handleRequest函式,作為createServer的引數,當http.Server例項接收到一個http請求時,會將請求資訊和請求響應物件傳給handleRequest函式,具體指將http.IncomingMessage的例項req,和http.ServerResponse的例項res傳給handleRequest函式。其中this.createContext函式的原始碼如下圖7

http.IncomingMessage和http.ServerResponse資訊可以參照node.js官網

圖7 createContext

圖7中createContext的主要作用是將請求資訊和響應資訊封裝在Request和Response類的執行例項中,並建立上下文類Context例項。context物件包含了Application、Request、Response等例項的引用。在this.callback方法中還有另一行很重要的程式碼,如下程式碼片段1。

程式碼片段1

const fn = compose(this.middleware);

可以從圖4中Application的構造方法中知道this.middleware是一個數組,該陣列用來儲存app.use方法傳入的中介軟體函式。Application的use方法具體程式碼實現細節如圖8,其中最關鍵的一行程式碼是this.middleware.push(fn)。

compose方法的程式碼實現包含在koa-compose包中,具體程式碼實現細節如圖9

圖9 compose

compose方法接收this.middleware陣列,返回一個匿名函式,該函式接收兩個引數,上下文例項context和一個next函式,執行該匿名函式會執行this.middleware陣列中的所有中介軟體函式,然後在執行傳入的next函式。匿名函式呼叫是在Application的callback方法中,在圖6的callback方法的最後將執行上下文物件和compose方法返回的匿名函式作為引數傳入this.handleRequest方法。接下來看一下this.handleRequest方法的具體細節,如圖9。

在this.handleRequest方法中建立了錯誤處理方法onError和返回響應的方法handleResponse。fnMiddleware就是compose方法返回的匿名函式。在this.handleRequest方法的最後執行匿名函式,並傳入hanldeResponse和onError函式分別處理正常請求響應流程和異常情況。

return fnMiddleware(ctx).then(handleResponse).catch(onerror);

執行fnMiddleware函式,實際上是執行之前傳入所有中介軟體函式。在中間函式中可以拿到上下文物件的引用,通過上下文物件我們可以獲取到經過封裝的請求和響應例項,具體形式如圖10。

圖10 中間間函式例子

在中介軟體方法中可以設定響應頭資訊、響應內容。以及讀取資料庫,獲取html模版等。將需要返回給使用者端的資料賦值給上下文物件context的body屬性。respond方法的具體實現如圖11。

圖11 respond

respond方法的主要作用是對返回的內容進行一些處理,然後呼叫node.js的http.ServerResponse例項的end方法,將具體內容返回給使用者端。

request.js和response.js

在Application的createContext方法中,將node.js的請求(http.IncomingMessage)和響應物件(http.ServerResponse)分別賦值給了Request類和Response類例項物件。Request中主要包含了處理請求的方法(實際上都是get方法,或者獲取器),獲取請求資料,例子如圖12。

上面的程式碼中this.req是http.IncomingMessage例項,包含了http請求資訊。Response中包含了處理請求響應的操作。例如設定響應狀態資訊,如圖13

其中this.res指http.ServerResponse物件例項。

到此處,圖1中三行程式碼的背後邏輯已分析完成。

154

Node.js

最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Istio 資料面日誌除錯