寫一個簡易中間件

NO IMAGE

目的

解決項目中代碼耦合度比較高,可以隨時對業務部分代碼進行插拔。

API 設計

applyMiddleWare(middleWares) //middleWares 傳入的中間件

返回值 fn //fn 為啟動中間件的方法

支持複合調用
applyMiddleWare(middleWare1, applyMiddleWare(middleWares), …..)

實現

我們假定有三個中間件:add, substract, multiply

順序是 add -> substract -> multiply

單箇中間件的設計是:

function MiddleWare(next) => {
return function(str){
next(str)
}
}

next為下一個啟動中間件的方法,思路其實很簡單,就是把multiply 的 裡面一層即 function(str){ next() } 這一層作為substract 的next,再依次往上掛,所以我們可以寫下如下代碼

function applyMiddleWare(middleWares){
var next = function(str){
return str;
};
middleWares = middleWares.reverse();
for(var i=0; i<middleWares.length; i++){
var next = middleWares[i](next);
}
return next;
}
」    

至於最裡面的那一層沒有next,我們又是從後往前遍歷中間件,所以入口的next 返一個 var next = function(str){ return str;}這個就好了,把處理的結果拋上去。

至於middleware複合的情況會有一點複雜,我們舉個例子:
applyMiddleWare(middleWare1, applyMiddleWare(middleWares))
middleWare1 的結構是 (next) => (str) => {}, applyMiddleWare(middleWares)的結構是 (str) => {}。我比較偷懶,打算把所有的組合都作為普通中間件,這裡用了一個contents記錄組合的中間件的,例如:

var start = applyMiddleWare(middleWares1, middleWares2, middleWares3);

那麼start的contents 就是[middleWares1, middleWares2, middleWares3],對於組合和非組合的用content字段區別,統一展開,類似數組展平,具體實現如下:

function add(next){
return function (str){  
console.log('add中間件before(準備+2):', str);  
str += 2;
str = next(str);
console.log('add中間件after:', str);  
return str;
}
}
function subtract(next){
return function(str){
console.log('subtract中間件before(準備-1):', str);  
str -= 1;
str = next(str);
console.log('subtract中間件after:', str);
return str;  
}
}
function multiply(next){
return function(str){
console.log('multiply中間件before(準備*2):', str);  
str *= 2;
str = next(str);
console.log('multiply中間件after:', str); 
return str; 
}
}
function flattenMiddleWare(middleWares){
var _array = [];
for(var i=0; i<middleWares.length; i++){
if(middleWares[i].isContents){
_array.push(...flattenMiddleWare(middleWares[i].isContents))
}else{
_array.push(middleWares[i]);
}
}
return _array;
}
function applyMiddleWare(middleWares){
var next = function(str){
return str;
};
middleWares = flattenMiddleWare(middleWares).reverse();
for(var i=0; i<middleWares.length; i++){
var next = middleWares[i](next);
}
next.isContents = middleWares;
return next;
}
function extraDivideMiddle(next){
return function(str){
console.log('divide中間件before(準備/0.5):', str);  
str /= 0.5;
str = next(str);
console.log('divide中間件after:', str); 
return str; 
}
}
//測試
var result = applyMiddleWare([extraDivideMiddle, applyMiddleWare([add, subtract, multiply]), extraDivideMiddle])(10);
console.log('result:', result);

結果

寫一個簡易中間件

相關文章

JAVA併發之多線程基礎(4)

JAVA併發之多線程基礎(3)

JAVA併發之多線程基礎(2)

JAVA併發之多線程基礎(1)