欢迎关注redux源码分析系列文章:
redux源码分析之一:createStore.js
redux源码分析之二:combineReducers.js
redux源码分析之三:bindActionCreators.js
redux源码分析之四:compose.js
redux源码分析之五:applyMiddlewareredux
redux的compose函数实在太精妙,总共才9行,真正的代码其实才1行,看下源文件代码以下:segmentfault
export default function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1) { return funcs[0] } return funcs.reduce((a, b) => (...args) => a(b(...args))) }
可是,就是这最后一行代码,不仔细分析,实在难以理解,我写了注释以下:数组
export default function compose(...funcs) { //若是参数长度为0,则返回一个最简单的函数,即传入什么,就返回什么的函数 if (funcs.length === 0) { return arg => arg } //若是参数长度为1,则将参数列表中的第一个函数做为返回值 if (funcs.length === 1) { return funcs[0] } //若是参数长度大于1,则对funcs列表执行reduce函数, //reduce方法会将(...args) => a(b(...args))总体做为一个返回值,赋值给a变量,b是funcs数组中的下一个函数 //一开始,a,是funcs数组中的第一个函数,b是funcs数组中第二个函数,每执行一次reduce操做,a会被reduce函数中的返回值从新赋值, // 而reduce函数的返回值刚恰好是一个函数,即a = (...args) => a(b(...args)), // 因为a就是一个函数,下一轮reduce,新的a函数又会把funcs中下一个函数b做为参数执行,并继续返回下一个a函数 //好比funcs = [f1, f2, f3, f4], 执行流程以下 // a1 = (...args) => f1(f2(...args)) // a2 = (...args) => a1(f3(...args)) // a3 = (...args) => a2(f4(...args)) // 依次代入,则获得 // a2 = (...args) => f1(f2(f3(...args))) // a3 = (...args) => f1(f2(f3(f4(...args)))) return funcs.reduce((a, b) => (...args) => a(b(...args))) }
因此,这个compose函数执行后,返回值是另一个函数,这个函数,其实只是作了一件事情:把一个函数数组,按照顺序,从数组最后向前按照顺序执行,而且,把前一个执行的函数返回值,做为下一个执行函数的入参。对,你没看错,就是这么简单!app