let step2 = (val) => val + 2
let step3 = (val) => val + 3
let step4 = (val) => val + 4
这几个函数组成一个任务队列
steps = [step4, step3, step2, init]
使用compose组合这个队列并执行
let composeFunc = compose(…steps)
console.log(composeFunc(1, 2, 3))
执行过程
6 -> 6 + 2 = 8 -> 8 + 3 = 11 -> 11 + 4 = 15
所以流程就是从init自右到左依次执行,下一个任务的参数是上一个任务的返回结果,并且任务都是同步的,这样就能保证任务可以按照有序的方向和有序的时间执行。
compose的实现
好了,我们现在已经知道compose是什么东西了,现在就来实现它吧!
最容易理解的实现方式
思路就是使用递归的过程思想,不断的检测队列中是否还有任务,如果有任务就执行,并把执行结果往后传递,这里是一个局部的思维,无法预知任务何时结束。直观上最容易理解。
const compose = function(…funcs) {
let length = funcs.length
let count = length - 1
let result
return function f1 (…arg1) {
result = funcs[count].apply(this, arg1)
if (count <= 0) {
count = length - 1
return result
}
count–
return f1.call(null, result)
}
}
删繁就简来看下,去掉args1参数
const compose = function(…funcs) {
let length = funcs.length
let count = length - 1
let result
return function f1 () {
result = funcscount
if (count <= 0) {
count = length - 1
return result
}
count–
return f1(result)
}
}
这就好看很多,我们假设有三个方法,aa,bb,cc
function aa() {
console.log(11);
}
function bb() {
console.log(22);
}
function cc() {
console.log(33);
return 33
}
然后传入compose
compose(aa,bb,cc)
此时count = 2,则下面其实是执行cc
result = funcscount
然后count–。再递归执行f1,则下面其实就是执行bb
result = funcscount
这样,就实现了 从funcs数组里从右往左依次拿方法出来调用,再把返回值传递给下一个。
后面的步骤同理。
这其实是一种面向过程的思想
手写javascript中reduce方法
为什么要手写?其实你要是能够很熟练的使用reduce,我觉得不必手写reduce,只是我觉得熟悉一下reduce内部的实现可以更好地理解后面的内容,况且 也不会太难呀!
function reduce(arr, cb, initialValue){
var num = initValue == undefined? num = arr[0]: initValue;
var i = initValue == undefined? 1: 0
for (i; i< arr.length; i++){
num = cb(num,arr[i],i)
}’
return num
}
如代码所示,就是先判断有没有传入初始值,有的话,下面的循环直接 从i = 0开始,否则i=1开始。
如果没有传入初始值,num就取 数组的第一个元素。这也是说明了为什么传入初始值,i就=1,因为第一个都被取出来了,就不能再取一次啦啦啦!
下面使用我们写的reduce方法
function fn(result, currentValue, index){
return result + currentValue
}
var arr = [2,3,4,5]
var b = reduce(arr, fn,10)
var c = reduce(arr, fn)
console.log(b) // 24
好了 ,没毛病,既然我们了解了reduce原理,就看看下面的redux中compose的实现吧
redux中compose的实现
function compose(…funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
debugger
return funcs.reduce((a, b) => (…args) => a(b(…args)))
}
很简短,非常的巧妙,但是不是很不好理解。不过没关系。
依旧通过例子来讲解。
function aa() {
console.log(11);
}
React
-
介绍一下react
-
React单项数据流
-
react生命周期函数和react组件的生命周期
-
react和Vue的原理,区别,亮点,作用
-
reactJs的组件交流
-
有了解过react的虚拟DOM吗,虚拟DOM是怎么对比的呢
-
项目里用到了react,为什么要选择react,react有哪些好处
-
怎么获取真正的dom
-
选择react的原因
-
react的生命周期函数
-
setState之后的流程
-
react高阶组件知道吗?
-
React的jsx,函数式编程
-
react的组件是通过什么去判断是否刷新的
-
如何配置React-Router
-
路由的动态加载模块
-
Redux中间件是什么东西,接受几个参数
-
redux请求中间件如何处理并发