Redux源碼閱讀_4

applyMiddleware.ts

函數(shù)重載聲明

首先是對(duì)applyMiddleware函數(shù)的重載峭沦,重載了七個(gè)函數(shù),主要是傳入?yún)?shù)個(gè)數(shù)的區(qū)別臀稚。

export default function applyMiddleware(): StoreEnhancer
export default function applyMiddleware<Ext1, S>(
  middleware1: Middleware<Ext1, S, any>
): StoreEnhancer<{ dispatch: Ext1 }>
export default function applyMiddleware<Ext1, Ext2, S>(
  middleware1: Middleware<Ext1, S, any>,
  middleware2: Middleware<Ext2, S, any>
): StoreEnhancer<{ dispatch: Ext1 & Ext2 }>
export default function applyMiddleware<Ext1, Ext2, Ext3, S>(
  middleware1: Middleware<Ext1, S, any>,
  middleware2: Middleware<Ext2, S, any>,
  middleware3: Middleware<Ext3, S, any>
): StoreEnhancer<{ dispatch: Ext1 & Ext2 & Ext3 }>
export default function applyMiddleware<Ext1, Ext2, Ext3, Ext4, S>(
  middleware1: Middleware<Ext1, S, any>,
  middleware2: Middleware<Ext2, S, any>,
  middleware3: Middleware<Ext3, S, any>,
  middleware4: Middleware<Ext4, S, any>
): StoreEnhancer<{ dispatch: Ext1 & Ext2 & Ext3 & Ext4 }>
export default function applyMiddleware<Ext1, Ext2, Ext3, Ext4, Ext5, S>(
  middleware1: Middleware<Ext1, S, any>,
  middleware2: Middleware<Ext2, S, any>,
  middleware3: Middleware<Ext3, S, any>,
  middleware4: Middleware<Ext4, S, any>,
  middleware5: Middleware<Ext5, S, any>
): StoreEnhancer<{ dispatch: Ext1 & Ext2 & Ext3 & Ext4 & Ext5 }>
export default function applyMiddleware<Ext, S = any>(
  ...middlewares: Middleware<any, S, any>[]
): StoreEnhancer<{ dispatch: Ext }>
函數(shù)實(shí)現(xiàn)
export default function applyMiddleware(
  ...middlewares: Middleware[]
): StoreEnhancer<any> {
  return (createStore: StoreEnhancerStoreCreator) => <S, A extends AnyAction>(
    reducer: Reducer<S, A>,
    preloadedState?: PreloadedState<S>
  ) => {
    const store = createStore(reducer, preloadedState)
    let dispatch: Dispatch = () => {
      throw new Error(
        'Dispatching while constructing your middleware is not allowed. ' +
          'Other middleware would not be applied to this dispatch.'
      )
    }

    const middlewareAPI: MiddlewareAPI = {
      getState: store.getState,
      dispatch: (action, ...args) => dispatch(action, ...args)
    }
    const chain = middlewares.map(middleware => middleware(middlewareAPI))
    dispatch = compose<typeof dispatch>(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

可以看到applyMiddleware返回一個(gè)對(duì)象旺垒,對(duì)象內(nèi)容為{...store, dispatch}宛裕。

首先看看定義的兩個(gè)接口 MiddlewareAPI與Middleware:

export interface MiddlewareAPI<D extends Dispatch = Dispatch, S = any> {
  dispatch: D
  getState(): S
}

export interface Middleware<
  _DispatchExt = {}, // TODO: remove unused component (breaking change)
  S = any,
  D extends Dispatch = Dispatch
> {
  (api: MiddlewareAPI<D, S>): (
    next: D
  ) => (action: D extends Dispatch<infer A> ? A : never) => any
}

可以看到,MiddlewareAPI是一個(gè)包含dispath與state屬性的對(duì)象牙勘,而Middleware是一個(gè)高階函數(shù)职恳,將Middleware寫(xiě)成函數(shù)形式,其結(jié)構(gòu)大致為:

function Middleware(api: ...) {
    return (next: ...) => (action: ...) {
        ...
    }
}

若在上面的結(jié)構(gòu)上做出如下類(lèi)型申明:

type Next<...> = (next: ...) => (action: ...) => any

則可以看做Middleware的返回值類(lèi)型是個(gè)Next方面。

回到applyMiddleware函數(shù)代碼中放钦,帶入?yún)?shù)看看函數(shù)內(nèi)部運(yùn)作。

若傳入?yún)?shù) middlewares = [middleware1, middleware2, middleware3]

則 chain = [next1, next2, next3]

由前文提到 compose實(shí)現(xiàn)( Redux源碼閱讀_2

dispatch = compose<typeof dispatch>(...chain)(store.dispatch)
????????????? =next1(next2(next3(store.dispatch)))

就是個(gè)逐層進(jìn)行函數(shù)運(yùn)算的操作恭金。

后記

redux源碼到這里就告一段落(還有個(gè)bindActionCreator函數(shù)實(shí)現(xiàn)沒(méi)整理操禀,但是平時(shí)沒(méi)怎么用到就不弄了),回到最開(kāi)始的問(wèn)題横腿,基本都是react-redux的內(nèi)容颓屑,這個(gè)之后再去看……

只有一個(gè)可以回到的問(wèn)題,action相關(guān)……

看看redux關(guān)于action的聲明

export interface Action<T = any> {
  type: T
}

就是一個(gè)包含type屬性的對(duì)象…… dispatch action的操作在前面關(guān)于dispatch函數(shù)的分析中也寫(xiě)到了……

文檔上寫(xiě)到的基本也就是源碼的所有內(nèi)容耿焊,不過(guò)只看文檔還是有點(diǎn)不知所云揪惦,結(jié)合源碼還是更能理解一點(diǎn)。(給自己找點(diǎn)借口……)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末搀别,一起剝皮案震驚了整個(gè)濱河市丹擎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌歇父,老刑警劉巖蒂培,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異榜苫,居然都是意外死亡护戳,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)垂睬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)媳荒,“玉大人抗悍,你說(shuō)我怎么就攤上這事∏恚” “怎么了缴渊?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)鱼炒。 經(jīng)常有香客問(wèn)我衔沼,道長(zhǎng),這世上最難降的妖魔是什么昔瞧? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任指蚁,我火速辦了婚禮,結(jié)果婚禮上自晰,老公的妹妹穿的比我還像新娘凝化。我一直安慰自己,他們只是感情好酬荞,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布搓劫。 她就那樣靜靜地躺著,像睡著了一般袜蚕。 火紅的嫁衣襯著肌膚如雪糟把。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天牲剃,我揣著相機(jī)與錄音遣疯,去河邊找鬼。 笑死凿傅,一個(gè)胖子當(dāng)著我的面吹牛缠犀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播聪舒,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼辨液,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了箱残?” 一聲冷哼從身側(cè)響起滔迈,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎被辑,沒(méi)想到半個(gè)月后燎悍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盼理,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年谈山,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宏怔。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奏路,死狀恐怖畴椰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鸽粉,我是刑警寧澤斜脂,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站潜叛,受9級(jí)特大地震影響秽褒,放射性物質(zhì)發(fā)生泄漏壶硅。R本人自食惡果不足惜威兜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望庐椒。 院中可真熱鬧椒舵,春花似錦、人聲如沸约谈。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)棱诱。三九已至泼橘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間迈勋,已是汗流浹背炬灭。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留靡菇,地道東北人重归。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像厦凤,于是被迫代替她去往敵國(guó)和親鼻吮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355