直接上代碼
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)))
}
核心在最后一行,用到了數(shù)組的reduce,reduce千萬不能看mdn的定義,會(huì)云里霧里的,我就在這里百思不得其姐,我們直接來看看一個(gè)數(shù)字對(duì)象的運(yùn)行結(jié)果
var bb= a.reduce((a, b) => {
console.log('a:',a,';b:', b)
return a
})

由結(jié)果可知,b是不斷地進(jìn)行數(shù)組遍歷的,a暫且理解成是上一次執(zhí)行之后返回的結(jié)果,我們來確認(rèn)下是不是這樣
var list = [12, 24, 34, 45, 53]
var result= list.reduce((a, b) => {
console.log('a:',a,';b:', b)
return a + b
})
console.log('result:', result)

果然如此,接下來我們把數(shù)字?jǐn)?shù)組改為函數(shù),看看執(zhí)行結(jié)果
function A() {
console.log(1)
}
function B() {
console.log(2)
}
function C() {
console.log(3)
}
function D() {
console.log(4)
}
[A, B, C, D].reduce((a,b)=>{
a()
b()
return a
})

假如不返回,會(huì)有什么結(jié)果

提示a不存在了,因?yàn)榈谝淮沃鬀]返回
有了以上的基本知識(shí)后,我們?cè)賮砜纯碿ompose的核心代碼
funcs.reduce((a, b) => (...args) => a(b(...args)))
由代碼可知,每次都返回了一個(gè)方法,而這個(gè)方法實(shí)現(xiàn)的效果是,每一次循環(huán),把當(dāng)前的節(jié)點(diǎn)方法執(zhí)行之后的結(jié)果作為下一個(gè)循環(huán)節(jié)點(diǎn)的輸入,假如有這么個(gè)數(shù)組[fun1,fun2,func3],那么執(zhí)行了了compose之后,會(huì)類似下面的結(jié)果
fun1(fun2(func3))
這就好比洋蔥,由里而外一層層的執(zhí)行
那么,在redux中,我們?cè)趺慈ダ斫馑兀鋵?shí),它主要用在applyMiddleware中,由createStore我們知道,中間件就是增強(qiáng)store功能的一個(gè)方式,比如支持異步,打印日志等
我們?cè)賮砜磳懸粋€(gè)實(shí)例,來理解一下這個(gè)增強(qiáng)器是怎么實(shí)現(xiàn)的
有如下的一個(gè)對(duì)象
{ dispatch: {}, store: 'default state' }
目前dispatch是空對(duì)象,我們希望執(zhí)行一些方法之后,它會(huì)多出一些屬性,那么,可以按照下面的代碼來實(shí)現(xiàn)
function compose(...funcs) {
if (funcs.length == 0) {
return
}
if (funcs.length == 1) {
return funcs[0]
}
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
function A(param) {
param = JSON.parse(JSON.stringify(param))
console.log('a:', param)
param.dispatch.a = 'a'
return param
}
function B(param) {
param = JSON.parse(JSON.stringify(param))
console.log('b:', param)
param.dispatch.b = 'b'
return param
}
function C(param) {
param = JSON.parse(JSON.stringify(param))
console.log('c', param)
param.dispatch.c = 'c'
return param
}
var s = compose(A, B, C)
s({ dispatch: {}, store: 'default state' })
來看看執(zhí)行的效果

這就是redux中中間件的基本思路了