redux中間件源碼分析(一)

廢話不多說奸汇,直接上干貨:

首先說下middleware怎么用

 store = createStore(reducer, applyMiddleware(middleware, middleware2));

下面先來看createStore里面干了什么拴驮,直接上源碼(去除了里面的方法)

export default function createStore(reducer, preloadedState, enhancer) {

  if (

    (typeof preloadedState === 'function' && typeof enhancer === 'function') ||

    (typeof enhancer === 'function' && typeof arguments[3] === 'function')

  ) {

    throw new Error(

      'It looks like you are passing several store enhancers to ' +

        'createStore(). This is not supported. Instead, compose them ' +

        'together to a single function.'

    )

  }
//這里主要做了一下參數(shù)處理送巡,讓enhancer正確指向applyMiddleware返回的函數(shù)
  if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {

    enhancer = preloadedState

    preloadedState = undefined

  }

  if (typeof enhancer !== 'undefined') {

    if (typeof enhancer !== 'function') {

      throw new Error('Expected the enhancer to be a function.')

    }
    //這里直接調(diào)用了applyMiddleware返回方法
    return enhancer(createStore)(reducer, preloadedState)

  }

  if (typeof reducer !== 'function') {

    throw new Error('Expected the reducer to be a function.')

  }

  let currentReducer = reducer

  let currentState = preloadedState

  let currentListeners = []

  let nextListeners = currentListeners

  let isDispatching = false
//沒有使用中間件的話直接返回store
  return {

    dispatch,

    subscribe,

    getState,

    replaceReducer,

    [$$observable]: observable

  }
}

看了上面createStore的源碼捧颅,我們有兩個(gè)結(jié)論:
1.在沒有使用中間件的時(shí)候,我們的createStore直接返回了一個(gè)store對象
2.在使用了中間件的時(shí)候我們的createStore直接調(diào)用了applyMiddleware返回的方法
問題:
在使用中間件的時(shí)候store在哪創(chuàng)建的黄锤?
別著急搪缨,下面我們來看applyMiddleware里面做了什么

export default function applyMiddleware(...middlewares) {
  return createStore => (...args) => {
    const store = createStore(...args)
    let dispatch = () => {
      throw new Error(
        'Dispatching while constructing your middleware is not allowed. ' +
          'Other middleware would not be applied to this dispatch.'
      )
    }

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

    return {
      ...store,
      dispatch
    }
  }
}

果然applyMiddleware返回一個(gè)方法(這里是一個(gè)柯里化的寫法)
在上面我們說過在使用中間件的時(shí)候createStore執(zhí)行的是一個(gè)applyMiddleware返回的方法,
并傳入了兩個(gè)參數(shù)

return enhancer(createStore)(reducer, preloadedState)
return createStore => (...args) => {}

再結(jié)合源碼鸵熟,都對上了此時(shí)createStore對應(yīng)的是上面?zhèn)鬟M(jìn)來的createStore副编,...args對應(yīng)的是上面?zhèn)魅氲?br> (reducer, preloadedState)
接著看這里

  //這個(gè)時(shí)候再調(diào)用createStore由于第二個(gè)參數(shù)不是一個(gè)方法,而且也不存在第三個(gè)參數(shù)流强,所以直接返回了store
const store = createStore(...args)

原來store是在這個(gè)地方創(chuàng)建的痹届,這里存在一個(gè)很隱蔽的遞歸調(diào)用呻待,終于知道了(松了一口氣)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市队腐,隨后出現(xiàn)的幾起案子蚕捉,更是在濱河造成了極大的恐慌,老刑警劉巖柴淘,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件迫淹,死亡現(xiàn)場離奇詭異,居然都是意外死亡为严,警方通過查閱死者的電腦和手機(jī)敛熬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來第股,“玉大人应民,你說我怎么就攤上這事≌耄” “怎么了瑞妇?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長梭冠。 經(jīng)常有香客問我辕狰,道長,這世上最難降的妖魔是什么控漠? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任蔓倍,我火速辦了婚禮,結(jié)果婚禮上盐捷,老公的妹妹穿的比我還像新娘偶翅。我一直安慰自己,他們只是感情好碉渡,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布聚谁。 她就那樣靜靜地躺著,像睡著了一般滞诺。 火紅的嫁衣襯著肌膚如雪形导。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天习霹,我揣著相機(jī)與錄音朵耕,去河邊找鬼。 笑死淋叶,一個(gè)胖子當(dāng)著我的面吹牛阎曹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼处嫌,長吁一口氣:“原來是場噩夢啊……” “哼栅贴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起熏迹,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤筹误,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后癣缅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體厨剪,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年友存,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了祷膳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,872評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡屡立,死狀恐怖直晨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情膨俐,我是刑警寧澤勇皇,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站焚刺,受9級特大地震影響敛摘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乳愉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一兄淫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蔓姚,春花似錦捕虽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至备闲,卻和暖如春晌端,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背浅役。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工斩松, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留伶唯,地道東北人觉既。 一個(gè)月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親瞪讼。 傳聞我的和親對象是個(gè)殘疾皇子钧椰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 在學(xué)習(xí)了redux過程中,了解到中間件這個(gè)名詞符欠,但是我看了十遍嫡霞,也完全就是懵逼的狀態(tài)。于是又重復(fù)敲了幾次代碼也不能...
    綽號陸拾柒閱讀 536評論 0 0
  • 寫在開頭 前置知識內(nèi)容希柿,閉包诊沪,高階函數(shù),函數(shù)式編程思想曾撤,redux核心概念端姚。 redux文檔:https://ww...
    前端開發(fā)愛好者閱讀 694評論 0 1
  • “中間件”這個(gè)詞聽起來很恐怖,但它實(shí)際一點(diǎn)都不難挤悉。想更好的了解中間件的方法就是看一下那些已經(jīng)實(shí)現(xiàn)了的中間件是怎么工...
    Jmingzi_閱讀 1,694評論 1 7
  • 原文: redux的applyMiddleware源碼 記得之前第一次看redux源碼的時(shí)候是很懵逼的渐裸,尤其是看到...
    xiaohesong閱讀 361評論 0 0
  • 中午練車回來路過園博園門口,看到一群初中生模樣的學(xué)生装悲,人手一機(jī)(手機(jī)+耳機(jī))昏鹃,不禁唏噓,時(shí)代真的不一樣了诀诊。 我大概...
    雪小樣閱讀 532評論 0 4