You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
让代码从右向左运行变成f1(f2(x)),4 -> f2 -> f1 -> 50,当然了你也可以在内部reverse一下让函数从第一个开始执行。
接下来我们看下实际运用的compose
letcompose=(...funs)=>(result)=>{for(vari=funs.length-1;i>-1;i--){result=funs[i].call(this,result);}returnresult;}varnumber=compose(Math.round,parseFloat)('5.8');// number => 6
Redux compose and middleware 源码分析
花了一天时间看了redux 几个function的源码感触颇深,接下来总结下源码的作用。
compose.js
https://github.com/reactjs/redux/blob/master/src/compose.js#L21
一头雾水啊,函数编程功力不够,第一眼懵逼,细细琢磨才领悟其中的奥妙。
先不谈奥妙之处我们先写段代码,慢慢解析。
下面代码我们需要组合2个函数,构建成一个新的函数
让代码从右向左运行变成f1(f2(x)),4 -> f2 -> f1 -> 50,当然了你也可以在内部reverse一下让函数从第一个开始执行。
接下来我们看下实际运用的compose
parseFloat函数return的结果作为Math.round函数的参数
Math.round(parseFloat('5.8'))`
我们在回到redux compose.js
跟上面的compose 的原理其实是一样一样的,就是写法很精妙。
先分析
reduce
这个methodreduce()把返回的结果继续和序列的下一个元素做累积计算,其效果就是上面这样。
拆分上面的源码步骤如下:
第一次 返回 (...args) => a(b(...args) 且与下一个c函数做计算
第二次 a 等于 (...args) => a(b(...args) ,b 等于 c 这个function , 然后再一次做 (...args) => a(b(...args)) 计算,就形成了
第三次也是如此
结果就如注释的一样
到这里我们这点了compose 的实现原理,接下来我们看下
applyMiddleware.js
中如何实现中间件的。
源码
然后我们看下middleware函数的签名
({ getState, dispatch }) => next => action => {...}
第一步把middlewares数组里的函数带着middlewareAPI这个参数都挨个执行个遍且,且保存在chain数组中。也就是middleware中的第一个参数,返回 next => action => {...}
第二步 就是上面composeJs 中组合chain中的函数。变成f1(f2(f3(store.dispatch))),并且最终保存在dispatch 变量中。里面的函数最终会返回action => {...} 这个函数 作为上一个函数的next参数保存在上个函数的scope中,所以每个middleware 中必须执行next(action)才能进入下个middleware。而最后一个middleware传入的next正是原始的store.dispatch。
基本的源码分析到此就差不多了,要注意的是为什么异步middleware中可以使用dispatch让action在重新执行一遍。因为其中的dispatch就是源码中的
这样异步middleware就非常容易理解,也很好巧妙的实现异步流。而next则是进入下一个middleware。如果在middleware里面滥用store.dispatch,就会造成无限的循环。
redux-thunk的实现就是判断action是否是function,如果是就执行action(),action就可以是一个异步请求的函数,具体可以看https://github.com/gaearon/redux-thunk/blob/master/src/index.js#L3的源码!
就写到这里,函数编程的巧妙还需多多学习呀,不足之处还请指正。
参考
Middleware
The text was updated successfully, but these errors were encountered: