单个函数的作用和功能相对来说是比较单一的,都应遵循单一职责的设计。
但在解决实际问题时,往往需要多个函数进行嵌套使用,这样就很容易写出不利于维护的洋葱代码,导致其可读性和可扩展性变差
fn5(fn4(fn3(fn2(fn1(x)))))
先内后外,一层一层执行:fn1() -> fn2() -> fn3() -> fn4() -> fn5
函数组合
-
设计思想
组合多个函数,同时返回一个新的函数。调用时组合函数的顺序按照
从右向左执行,右边函数调用后的返回结果作为左边函数的传入参数,严格保证函数的执行顺序遵循「多用组合,少用继承」的代码设计原则 -
核心作用
将嵌套执行的函数进行扁平化平铺,让代码逻辑更清晰,从而
提高代码的可读性和可扩展性把多个功能单一的函数进行组合,来共同完成一个复杂业务目标,体现了
分而治之,合而用之的微服务思想 -
应用场景
将功能复杂的函数拆解成多个功能相对单一的函数,可以进行任意组合,使多个单一的功能函数实现策略化
{ test: /\.scss$/, use: ["style-loader", "css-loader", "sass-loader"] }经典应用场景:
Webpack中loader的加载顺序也是从右向左通过函数组合实现的
源码分析及强化
-
优秀源码
const compose = (...funcs) => { const len = funcs.length if (len === 0) { return arg => arg } if (len === 1) { return funcs[0] } return funcs.reduce((a, b) => (...args) => a(b(...args))) }把后一个函数的执行结果作为包裹着前面函数的空函数的参数,传入执行 -
强化源码
const compose = (...funcs) => { const len = funcs.length if (len === 0) { return arg => arg } if (len === 1) { return funcs[0] } return funcs.reduce((a, b) => async (...args) => a(await b(...args))) }由于优秀源码不支持异步函数,所以对其进行适配,以满足更多业务场景一起学习,加群交流看 沸点