目的
解决项目中代码耦合度比较高,可以随时对业务部分代码进行插拔。
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
至于最里面的那一层没有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