个人理解:执行某个函数之前,可以得到并修改调用这个函数要传的参数,目的就是对参数的校验,加工,或者记录,使这个函数在接收到自己处理不了的参数时,能够在这些中间的函数,将参数转化成自己可以处理的参数,这个过程实际就是redux中间件的工作流程。 举个例子 假如有三个中间件函数,中间件函数是一个工厂函数,为了简单,这里调用两次就ok
// 函数a
const a = dispatch => action => {
console.log('a');
if (action === '孙子') {
action = '亲人';
}
return dispatch(action);
};
// 函数b
const b = dispatch => action => {
console.log('b');
if (action === '儿子') {
action = '亲人';
}
return dispatch(action);c
};
// 函数c
const c = dispatch => action => {
console.log('c');
if (action === '孩子') {
action = '亲人';
}
return dispatch(action);
};
我们想执行console.log('孙子'),例子举得不好,将就看 想在执行之前执行上面三个函数,并且把参数'孙子'传进去,看看这个参数是不是亲人, 首先把上面三函数聚合,compose,将参数用函数包裹起来,右边的函数把左边的函数执行结果当参数,这过程中没执行一个函数哦
function compose(...arg){
return arg.reduce((x,y)=>(...args)=>y(x(...args)))
}
let china=compose(a,b,c)
china值为
image.png
调用china 得到新的console.log,这个newConsole就时上面三个函数的聚合,并且可以得到action,检查action,
let newConsole=china(console.log)
试一下
newConsole.log('孙子')
image.png
是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。 // 实现一个add方法,使计算结果能够满足如下预期: add(1)(2)(3) = 6; add(1, 2, 3)(4) = 10; add(1)(2)(3)(4)(5) = 15;
const add=(...arg)=>{
// 第一次执行时,定义一个数组专门用来存储所有的参数
const args=arg;
//创建一个新fn
let _add=(...newArg)=>{
//每次调用都合并一下参数,保证参数是所有的
args.push(...newArg)
//每次调用返回这个函数本身
return _add;
}
//利用toString隐式转换功能把值计算出并return 出去
_add.toString=()=>{
return args.reduce((a,b)=>a+b)
}
//返回新的fn
return _add;
}
柯里化封装,这里封装的是指定了函数参数长度,当参累计到该函数所需要参数时返回结果,否则返回中间函数
function createCurry(func, oldArgs=[]) {
//保存函数需要的参数个数(函数名.length获取的是函数形参个数,所以这里限制了es6箭头函数,那就不灵了)
var fnArgsLen = func.length;
//闭包的方式缓存这些参数,第一次是初始的,后面每次拿到最新合并的
var allArgs = oldArgs ;
// @返回的函数
return function(...newArgs) {
//新的参数和老参数合并
allArgs.push(...newArgs);
// 如果参数个数小于func执行所需要的参数,则递归调用createCurry,返回 @返回的函数,继续等待收集参数
if (allArgs.length < fnArgsLen) {
return createCurry(func,allArgs)
// 或者 return createCurry.call(this, func, allArgs );
}
// 参数收集完毕,则执行func
return func.apply(this, allArgs);
}
}
举个例子 sum方法接受3个参数,必须够三个参数才会有结果
function sum(a,b,c){
//这个应该是return 语句
console.log([a,b,c].reduce((a,b)=>a+b))
//这是新的收集开始(瞎写的)
return createCurry(sum);
}
试一下
createCurry(sum)(3)(3)(3)(3)(3)(19)
image.png