function add1(num) { console.log('add1'); return num + 1 } function add2(num) { console.log('add2'); return num + 2 } function add3(num) { console.log('add3'); return num + 3 } function square(num) { console.log('square'); return num * num } // 同一个参数给多个函数执行 - 合成函数 console.log('合成写法-函数嵌套:', square(add3(add2(add1(0))))) // 函数合成 - compose const compose = (...args) => { return function(num) { let ret = num for (let i = 0; i < args.length; i++) { ret = args[i](ret) } return ret } } console.log('合成写法-compose:', compose(add1, add2, add3, square)(0)); // es6 reduce版本 const composeES6 = (...args) => { // 第一次用reduce实现 // return function(num) { // let ret = args.reduce((fn1, fn2) => { // return (arg) => { // return fn2(fn1(arg)) // } // }) // return ret(num) // } // reduce精简版 - 果然还是要对reduce的了解要深入啊 return function(num) { // Array的reduce(callback, arg)方法,使用上一次callback的执行结果作为参数 // 如果arg存在,则执行第一个callback的第一个参数为arg return args.reduce((prev, next) => { // 第一次add1(num) 返回arg1 // 第二次add2(arg1) 返回arg2 // 第三次add3(arg2) 返回arg3 // 第四次square(arg3) 返回arg4 没有下一个,最终返回arg4 return next(prev) }, num) } } console.log('es6-reduce-compose写法:', composeES6(add1, add2, add3, square)(0));
洋葱模型,普通写法:
function addFn1(next, ...args) { console.log('addFn1 start', args); next() console.log('addFn1 end'); } function addFn2(next, ...args) { console.log('addFn2 start', args); next() console.log('addFn2 end'); } function addFn3(next, ...args) { console.log('addFn3 start', args); next() console.log('addFn3 end'); } // 普通写法 极难理解 const myNext = () => { console.log('这里写我要处理的方法') } let composeYang = (myNext) => addFn1(() => addFn2(() => addFn3(myNext)))
const compose1 = (fns) => { return (myNext, ...args) => { let ret = myNext.bind(null, args) for (let i = fns.length - 1; i >= 0; i--) { let fn = fns[i] let oldRet = ret ret = () => fn(oldRet, args) } return ret() } } const composeYang = compose1([addFn1, addFn2, addFn3]) composeYang(myNext, '我是参数1', '我是参数2')
评论区