解决项目中代码耦合度比较高,能够随时对业务部分代码进行插拔。数组
applyMiddleWare(middleWares) //middleWares 传入的中间件app
返回值 fn //fn 为启动中间件的方法ide
支持复合调用 applyMiddleWare(middleWare1, applyMiddleWare(middleWares), .....)测试
咱们假定有三个中间件:add, substract, multiplyspa
顺序是 add -> substract -> multiply设计
单个中间件的设计是:code
function MiddleWare(next) => {
return function(str){
next(str)
}
}
复制代码
next为下一个启动中间件的方法,思路其实很简单,就是把multiply 的 里面一层即 function(str){ next() } 这一层做为substract 的next,再依次往上挂,因此咱们能够写下以下代码cdn
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记录组合的中间件的,例如:blog
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);
复制代码