首先,请看redux源码
let componse = (...fns) => fns.reduce((a, b) => (...args) => a(b(...args)));
如果要你实现一个componse函数,可能你会用这种方式;
function componse(...fn){
return (...args)=>{
let lastFn = fn.pop();
//console.log(lastFn);
return fn.reduceRight((result,item)=>{
//console.log(result);
return item(result);
},lastFn(...args));
}
}
升级版:
let componse = (...fns)=>(...args)=>fns.reduceRight((result,item)=>item(result),fns.pop()(...args));
以上两种都比较好理解的;都是利用reduceRight从右边到左,依次执行。
但是redux源码这就比较难理解了,他利用的是reduce,很明显,reduce迭代是从左往右的,
那是它是怎么实现参数从右往左遍历的呢???
那是它是怎么实现参数从右往左遍历的呢???
那是它是怎么实现参数从右往左遍历的呢???
解
先看下我给你们解开后源码样子,和我自己定义的例子:
function num(num) {
console.log(arguments);
return ++num;
}
function add(num) {
console.log(arguments);
return num + num;
}
function minus(num) {
console.log(arguments);
return num - 1;
}
//redux componse源码
function componse(...fns) {
return fns.reduce(function (a, b) {
// console.log(a,b,'上');
return function (...args) {
// console.log(a,b,'下');
return a(b(...args));
}
})
}
console.log(componse(minus, add, num)(5));
那当然还是利用的闭包嘞;说的简单,是怎么用的呢?是这样啊,首先先说一下,reduce,它是把上一次返回的结果在这一次拿来使用,以达到叠加的效果。就像上面我们常规实现componse函数一样。
但是,你看redux每次reduce返回的是什么?他是函数,你看啊!这就是关键,如果返回的是一个函数的话,a(b(args))
他会是这种效果,Funtion(Function(Function sum(args)));但是他们这里的Function虽然长得一样,但是可不是一个函数哦!他们是这样的minus(add(sum(args)));
这里利用了柯里化函数思想,把每个函数先给存储起来,后来的递归时在进行使用!!!
欧克,不理解的地方,欢迎讨论、指点,想通这些,不容易啊!