通过reduce实现redux中的compose

在es6中,我们可以使用promise来解决‘回调地狱’的问题,但是在一些应用场景中我们还会遇到另一种‘地狱’:函数的深度嵌套调用,此时我们就可以用compose函数来扁平化这种调用,提升代码可读性。

提出问题

假设有这么一段代码:

function f1(data) {
  	console.log('f1执行')
  	return data+1
  }
  function f2(data) {
  	console.log('f2执行')
  	return data+2
  }
  function f3(data) {
  	console.log('f3执行')
  	return data+3
  }
  function f4(data) {
  	console.log('f4执行')
  	return data+4
  }

现在要求执行这几个函数时要传入上一个函数的执行结果作为参数,此时代码写起来是这样的:

f1(f2(f3(f4(3))))

执行起来是没有问题,但是看起来难受且代码不好维护。
此时如果使用compose函数,代码就是这样写的:

compose(f1,f2,f3,f4)(3)

代码看起来清新很多。
compose函数执行完会返回一个新的函数,这个函数接受最初始的参数,然后将这个参数传给f4,f4执行完后把结果传给f3,依次类推,最后把f1的执行结果返回出来。有了思路,实现起来就很容易了。

代码实现

首先定义一个函数compose,首先数组化arguments 然后返回一个闭包,这个闭包接受一个参数作为嵌套调用的初始参数。

function compose(){
  	let fns=Array.from(arguments)
  	return function(data){}
  	}

此时fns数组是这个样子的

[f1,f2,f3,f4]

我们希望最先执行f4最后执行f1,即函数从右到左依次执行,此时就要对数组进行reverse操作,之后再对fns数组进行reduce操作,我们把闭包函数接收的参数作为reduce的初始值,并在reduce操作函数中的total作为参数传currentValue函数中并执行,最后把currentValue函数执行结果返回作为total值传入到下一次的操作中,最终代码如下:

function compose(){
		let fns=Array.from(arguments)
		return function(data){
            return fns.reverse().reduce(function(pre,item){
                 return item(pre)
             },data)
		}
	}

最后来执行一下代码:

     console.log('normal')
     console.log('结果是'+f1(f2(f3(f4(3)))))
     console.log('useCompose')
	 console.log('结果是'+compose(f1,f2,f3,f4)(3))

执行结果:
通过reduce实现redux中的compose_第1张图片

实际开发中的应用

在使用react开发高阶组件时,我们除了使用装饰器的方式来对木偶组件进行增强以外,还可以使用compose来把智能组件和木偶组件链接起来以得到我们最后需要的组件。

你可能感兴趣的:(js,js,javascript)