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