Express中介軟體原理詳解

寒東設計師發表於2019-03-04

前言

      Express和Koa是目前最主流的基於node的web開發框架,他們的開發者是同一班人馬。貌似現在Koa更加流行,但是仍然有大量的專案在使用Express,所以我想通過這篇文章說說Express中介軟體的原理。

中介軟體的功能和分類

      中介軟體的本質就是一個函式,在收到請求和返回相應的過程中做一些我們想做的事情。Express文件中對它的作用是這麼描述的:

執行任何程式碼。
修改請求和響應物件。
終結請求-響應迴圈。
呼叫堆疊中的下一個中介軟體。

分類

      Express文件中把他們分為了五類,但是他們的原理相同,只是用法不同:

應用級中介軟體
路由級中介軟體
錯誤處理中介軟體
內建中介軟體
第三方中介軟體

中介軟體的原理

      首先我們看看中介軟體的用法:

var express = require('express')
var app = express();
app.use('/user', function (req, res, next) {
  //TODO
  next();
});
app.listen(8080)

複製程式碼

      接下來我們對比看一下下原始碼:

Express中介軟體原理詳解
      與中介軟體有關的有三部分:

  • express.js繼承application.js並對外暴露介面
  • application.js掛載了所有核心方法
  • router資料夾處理路由邏輯

      先看express.js的程式碼:

Express中介軟體原理詳解

      這部分程式碼中最重要的是紅色方框部分,mixin是一個第三方庫。可以簡單理解為繼承(實際上它不是繼承而是混合)。

      接下來我們看application.js:

Express中介軟體原理詳解

      我把檔案下載下來並且刪去了註釋,通過這張圖我們可以看出這個檔案的作用是掛載了所有的方法(包括use等關鍵api)。
      這裡面比較重要的是use方法,它的作用就是把我們用app.use註冊的所有中介軟體和路由方法交給Router類來處理。
      那我們再看看router資料夾類的結構:

Express中介軟體原理詳解

      index.js是入口檔案,處理所有的路由;
      layer.js中宣告瞭Layer類,處理每一層路由中介軟體或者每一個子中介軟體;
      router.js中宣告瞭Router類,處理每一個子路由。
      這裡面有一個子中介軟體的概念,對應Exprees文件中有這一句話:

另外,你還可以同時裝載一系列中介軟體函式,從而在一個掛載點上建立一個子中介軟體棧。

      這句話的意思是說我們可以把程式碼寫成下面這種形式:

app.use('/user1', function fn1(req, res, next) {
  // TODO
  next();
}, function fn2(req, res, next) {
  //TODO
  next();
});
app.use('/user2', function fn3(req, res, next) {
  // TODO
  next();
}, function fn4(req, res, next) {
  //TODO
  next();
});
複製程式碼

      上面的程式碼給user1和user2分別建立了一個子中介軟體棧。這種語法的實現就是靠Layer類實現的。
      畫一張圖來解釋上面的程式碼:

Express中介軟體原理詳解

      解釋一下上面的程式碼和圖:
      我們寫了兩個路由/user1和/user2,每個路由給了兩個處理函式。對於這段程式碼,Express是這樣處理的:

  1. 在index.js檔案中,定義了一個stack陣列,接下來會建立兩個Layer放到這個stack中。
  2. route.js模組會給/user1再建立一個stack和fn1、fn2兩個Layer
  3. /user2同/user1
  4. 最後,Express會從上往下執行每個Layer裡的函式,對應到圖上就是從上至下、從左至右的依次執行,順序為fn1、fn2、fn3、fn4。

最後

      以上就是Express中介軟體的簡單原理,白話較多,如果寫的不準確的地方,希望大家批評指正。

參考資料

Express官網
Express的github倉庫地址

相關文章