何為中介軟體
我理解的中介軟體是一種能夠將資料進行管道化處理的程式設計技術,每個中介軟體負責處理一部分資料,最終組合成一條具有資料處理能力的管道。這種程式設計技術最早可能來自於函數語言程式設計領域,在前端技術領域中最知名的應用案例當屬於 Redux 和 Koa 這兩個庫,網上有很多分析兩個庫關於中介軟體的原始碼實現,但鮮有文章分析兩者設計上的區別,於是就有了這篇聊聊
中介軟體管道的設計
Redux
如果你探究過兩者的原始碼,應該不難發現同樣是中介軟體,但是兩者在構建中介軟體管道上採用了兩種不同的程式設計技術,Redux 使用的是源於 reduce 函式,通過特定的中介軟體函式簽名,將中介軟體函式不斷合併最終變成一個階梯式的巢狀函式,這個巢狀函式就是被包裝過的 dispatch ,有意思的是,如果中間內部呼叫了 dispatch 則整個巢狀函式會被重新執行,這個特性保證了所有中介軟體的有序執行,但如果你的中介軟體中有非同步程式碼,那就會變得有點不如預期,甚至有點糟糕了,由此我們可以得到一個設計上的結論,Redux 的中介軟體管道是同步處理所有的資料,同時它也支援重置整個處理流程,實現上通過函式巢狀而非遞迴,執行順序上有很有意思,第一個中介軟體的next函式的之前的程式碼最先執行,next函式之後的程式碼則最後執行,整個中介軟體管道其實是基於next函式鏈的一個環形管道,可以得到如下這張圖。
Koa
相比 Redux 中介軟體的複雜機制,Koa 實現上就簡單多了,非常直接的遞迴實現,然後就是對中介軟體函式的一些限制,比如不能呼叫兩次的 next, 不然就給你一個大大的 Error :-{ ,同時為了解決非同步中介軟體的問題, Koa 引入了 async/await,從執行機制上抹平了同步非同步程式碼的差異, 當然前提是你按照規範書寫你的程式碼,不同於 Redux 的中間通過傳遞處理後的 action 的擊鼓傳花,Koa 通過向所有中介軟體注入 ctx 物件完成資料的處理。
讓我們總結下
從 Redux 的角度,中介軟體的機制是為了擴充套件 action 裝載資料的能力,畢竟在 FLUX 架構中,action 非常簡單卻又極其重要,正因為 action 被設計的很簡單,當我們需要完成複雜的功能,就需要一種強大的擴充套件 action 能力,能夠讓 action 裝載不同型別的資料,甚至是函式,從而將整個應用的資料流能夠管理起來,而不至於因為 action 無法裝載某種資料,導致資料流的洩露。這種設計理念也同樣適用於對 Redux 中介軟體的設計, 當我們考慮將某些通用的功能或者業務放在 Redux 中介軟體中去實現和處理的時候,不應該將中介軟體定義為某種業務功能,而應該從 action 的角度去設計中介軟體,從處理所有的 action 和 處理某種具有明確語義的 action 這兩點來設計我們的中介軟體,即中介軟體本身存在兩種大的型別
- 全域性 action 處理,例如 logger
- 具有明確語義的 action 處理,可分為兩類
- 業務型, 例如 埋點的處理
- 功能型, 例如 thunk, promise
不同於 Redux 只傳遞一個 action,Koa 要處理的是一對 Req/Res 資料模型,它的型別是不可變的,即我們不能設計說有一種全域性的 Req/Res,有一種業務的,我們會說 Koa 的中介軟體有全域性的,業務的,因為設計的重點在於中介軟體而不是中介軟體處理的資料,所以 Req/Res 就可以作為 ctx 的一部分成為中介軟體管道的上下文, 而我們設計 Koa 中介軟體的時候,就會把關注點放在中介軟體本身,而不是像 Redux 那樣先考慮 action 的型別, 再定義中介軟體,所以 Redux 和 Koa 中介軟體的最大區別,我想用一句話就足以概括了。
In Reudx is ActionMiddleware,In Koa is Middleware
打個小廣告:挖財 無線 & 前端團隊求賢若渴,如果你喜歡各種新奇的 Cool 的技術,喜歡搗鼓各種工具, 喜歡研究架構,本團隊提供各種環境和機會,歡迎簡歷來投,流程超快,當天出籤,急速入職!!!