知识科普
compose就是按从右至左的顺序依次执行函数数组里面的每一个函数, 并把上一次函数执行返回的结果作为下一次函数的参数。其中只有第一个函数是多元函数(可以接收多个参数)
背景介绍
js是一门非常灵活的语言, 集合了好多语言的特性和多种编程模式, 对于componse的实现, 就有非常多的思路, 每一种思路独树一帜, 各领风骚, 实现之后, 犹如拨开云雾见天日, 一个字, 爽! 包括但不至于以下实现思路:
- 面向过程(递归)
- 函数组合(reduce)
- Promise(sequence)
1.面向过程/递归
这个思路就是使用递归的过程思想,不断地检测队列中是否还有任务,如果有任务就执行, 并把执行结果往后传递. 优点: 直观上最容易结束和理解, 也易于实现 缺点: 无法预知任务何时结束(实际上这也是递归的缺点)
const compose = function(args) {
let length = args.length
let count = length - 1
let result
return function f1(...argsF1) {
result = args[count].apply(this, argsF1)
if(count <=0 ) {
return result
}
count --
return f1.call(null, result)
}
}
let a = function(a, b){ return a + b}
let b = function(a){ return a * a}
let c = function(a){ return a * a +10}
let steps = [c, b, a]
let composeFunc = compose(steps)
console.log(composeFunc(1, 2)) // 91
2.函数组合/reduce
compose是函数式编程中使用较多的一种写法, 它把逻辑解耦在各个函数中, 通过compose的方式组合函数, 将外部数据依次通过各个函数的加工, 生成结果. 话不多说, 上代码 --
let a = function(a, b){console.log(1); return a + b}
let b = function(a){ console.log(2); return a * a}
let c = function(a){ console.log(3); return a * a + 10}
let steps = [c, b, a]
let reducer = (acc, cur) => (...x) => acc(cur(...x))
let compose = steps.reduce(reducer)
console.log(compose(1, 2)) // 91
参考来源: 函数式编程中的compose zhuanlan.zhihu.com/p/103515893
3.Promise
上代码
let a = function(a, b){console.log(1); return a + b}
let b = function(a){ console.log(2); return a * a}
let c = function(a){ console.log(3); return a * a + 10}
let steps = [c, b, a]
const compose = function(...steps) {
let init = steps.pop()
return function(...args) {
return steps.reverse().reduce(function(sequence, func) {
return sequence.then(function(result) {
return func.call(null, result)
})
}, Promise.resolve(init.apply(null, args)))
}
}
console.log(compose(...steps)(1, 2).then(res => console.log(res))) // 91
注意事项: 因为then回调返回的是一个promise实例对象, 所以最后需要加多一个then回调来拿结果
使用compose的好处
- 提高函数的独立重用和可维护性
- 增强功能的扩展性
在实际业务中的应用
包括但不限于以下:
-
在需要处理复杂数据转换的时候, 比如后台给前端的响应数据转换到页面交互展示需要的数据的时候, 转换数据的逻辑可能比较复杂, 这个时候通常需要拆分成多个颗粒度比较小的函数来分别处理. 在提交表单数据的时候, 可能又要进行一次复杂转换, 把页面交互展示的数据格式转换成后台所需的数据格式.
-
在对一些文件做前端处理例如做excel文件的上传下载处理或者需要转换成table展示的时候, 中间步骤比较多, 可能需要做层层转换处理. 比如excel数据转table的时候, 可能要对excel中第一行的 每一个单元格做英文到中文的转换(对应table的每一列的表头), 除第一行的每一个单元格可能要做非空效 验或者其它规则校验(注意: 这里的excel是人工编辑上传的, 所以要做多种规则校验). 后台json数据转table同理.
-
为便于功能实现, 针对第三方库的封装, 中间过程比较复杂的场景
总结:
1. 个人认为第二种是最佳实践, 原因包括但不限于: 代码量也最少, 使用最简便(只有一个'()'),稍有点小缺点是可读性略差, 使用之前需要彻底理解这种思路的实现机制和过程.
2. 使用递归的方法对新人最友好
3. 后面两种方法使用的是ES6的语法, 需要注意浏览器兼容 **
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!