最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 蒙娜丽莎, 她是谁? 带你揭开compose的神秘面纱!

    正文概述 掘金(阿里阿多)   2021-04-17   582

    知识科普

    compose就是按从右至左的顺序依次执行函数数组里面的每一个函数, 并把上一次函数执行返回的结果作为下一次函数的参数。其中只有第一个函数是多元函数(可以接收多个参数)

    背景介绍

    js是一门非常灵活的语言, 集合了好多语言的特性和多种编程模式, 对于componse的实现, 就有非常多的思路, 每一种思路独树一帜, 各领风骚, 实现之后, 犹如拨开云雾见天日, 一个字, 爽! 包括但不至于以下实现思路:

    1. 面向过程(递归)
    2. 函数组合(reduce)
    3. 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的好处

    1. 提高函数的独立重用和可维护性
    2. 增强功能的扩展性

    在实际业务中的应用

    包括但不限于以下:

    1. 在需要处理复杂数据转换的时候, 比如后台给前端的响应数据转换到页面交互展示需要的数据的时候, 转换数据的逻辑可能比较复杂, 这个时候通常需要拆分成多个颗粒度比较小的函数来分别处理. 在提交表单数据的时候, 可能又要进行一次复杂转换, 把页面交互展示的数据格式转换成后台所需的数据格式.

    2. 在对一些文件做前端处理例如做excel文件的上传下载处理或者需要转换成table展示的时候, 中间步骤比较多, 可能需要做层层转换处理. 比如excel数据转table的时候, 可能要对excel中第一行的 每一个单元格做英文到中文的转换(对应table的每一列的表头), 除第一行的每一个单元格可能要做非空效 验或者其它规则校验(注意: 这里的excel是人工编辑上传的, 所以要做多种规则校验). 后台json数据转table同理.

    3. 为便于功能实现, 针对第三方库的封装, 中间过程比较复杂的场景

    总结:

    1. 个人认为第二种是最佳实践, 原因包括但不限于: 代码量也最少, 使用最简便(只有一个'()'),稍有点小缺点是可读性略差, 使用之前需要彻底理解这种思路的实现机制和过程.

    2. 使用递归的方法对新人最友好

    3. 后面两种方法使用的是ES6的语法, 需要注意浏览器兼容 **


    起源地下载网 » 蒙娜丽莎, 她是谁? 带你揭开compose的神秘面纱!

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元