首页 > JavaScript > 函数式编程 - compose的各种姿势

函数式编程 - compose的各种姿势

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')

评论区

粤ICP备15040393号-1