compose是什么
compose 是函数式编程中一个非常重要的函数,compose的函数作用就是组合函数,将需要嵌套执行的函数扁平化处理。将多个函数串联起来,上一个函数的输出作为下一个函数的输入。
这是redux中源码中compose的实现
/**
* Composes single-argument functions from right to left. The rightmost
* function can take multiple arguments as it provides the signature for
* the resulting composite function.
*
* @param {...Function} funcs The functions to compose.
* @returns {Function} A function obtained by composing the argument functions
* from right to left. For example, compose(f, g, h) is identical to doing
* (...args) => f(g(h(...args))).
*/
function compose() {
for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) {
funcs[_key] = arguments[_key];
}
if (funcs.length === 0) {
return function (arg) {
return arg;
};
}
if (funcs.length === 1) {
return funcs[0];
}
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
前面是一些参数和边界处理,我们重点看一下最后reduce函数部分
funcs.reduce((a, b) => (...args) => a(b(...args)))
很短,很巧妙,但是不好理解。下面通过例子来分析一下:
function aa() {
console.log(11);
}
function bb() {
console.log(22);
}
function cc() {
console.log(33);
}
假设只有这三个方法,我们怎样才能先执行cc再执行bb,再执行aa呢? 没错,可以直接写
aa(bb(cc()))
就是这样,非常巧妙,不仅完成了执行顺序,还实现了前一个方法执行返回的结果传递给了下一个即将要执行的方法。
而下面这段代码所做的就是将funcs数组[aa,bb,cc],转化成aa(bb(cc()))
funcs.reduce((a, b) => (...args) => a(b(...args)))
怎么办到的?下面举例解释一下:
reduce内部第一次执行返回的结果是 一个方法
(...args) => aa(bb(...args))
我们现在把这个方法简化成dd,即
dd = (...args) => aa(bb(...args))
reduce内部第二次执行的时候,此时的a 是 上一次返回的dd方法,b是cc
所以执行结果是
(...args) => dd(cc(...args))
而dd(cc(...args))不就是先执行cc再执行dd吗?而dd就是执行bb再执行aa。现在应该懂了吧
网友评论