摘要:的中間件主要是通過(guò)模塊實(shí)現(xiàn)的。返回的也是一個(gè)對(duì)象這個(gè)其實(shí)就是,各個(gè)中間件的最底層第三層的哪個(gè)函數(shù)組成的圓環(huán)函數(shù)構(gòu)成的這就是對(duì)源碼的一個(gè)整體解讀,水平有限,歡迎拍磚。后續(xù)的源碼解讀和測(cè)試?yán)涌梢躁P(guān)注源碼解讀倉(cāng)庫(kù)
applyMiddleware源碼解析
中間件機(jī)制在redux中是強(qiáng)大且便捷的,利用redux的中間件我們能夠?qū)崿F(xiàn)日志記錄,異步調(diào)用等多種十分實(shí)用的功能。redux的中間件主要是通過(guò)applyMiddleware模塊實(shí)現(xiàn)的。下面,我們就好好的看一下,這個(gè)模塊到底有什么神奇的魔力。
關(guān)于中間件的使用,不了解的同學(xué)還需要參考redux文檔進(jìn)行學(xué)習(xí)。
在我們進(jìn)行中間件源碼剖析之前,我們需要知道一件事:中間件模塊在redux的源碼中是怎么被被調(diào)用的?只有明白了這個(gè)問(wèn)題,我們才能夠知道各個(gè)參數(shù)分別代表的是什么含義。
中間件的本質(zhì)是作為enhancer而存在的。所以,它是通過(guò)createStore方法傳遞到redux的內(nèi)部中的。在[createStore源碼分析]()中有這樣一段代碼:
if (typeof enhancer !== "undefined") { if (typeof enhancer !== "function") { throw new Error("Expected the enhancer to be a function.") } return enhancer(createStore)(reducer, preloadedState) }
從這段代碼中,我們不難看出,中間件模塊是一個(gè)高階函數(shù)。其函數(shù)簽名可以表述如下:
const applyMiddleware = (各個(gè)中間件列表) => (createStore(創(chuàng)建store)) => (reducer(reducer集合), preloadedState(初始state)) => {}
明白了上面的那個(gè)問(wèn)題,還有一個(gè)問(wèn)題是我們需要知道的--就是redux的中間件的形式是怎么樣的?這里,我們選擇了用于處理異步的中間件redux-thunk的源碼,為大家解釋一下。(看到代碼,只想說(shuō),臥槽臥槽臥槽)。
function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => next => action => { if (typeof action === "function") { return action(dispatch, getState, extraArgument); } return next(action); }; } const thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; export default thunk;
而在redux中我們應(yīng)該怎么使用它?
createStore(reducers, applyMiddleware(thunk))
到這里,我們知道了redux是怎么使用中間件的。下面,我們就要詳細(xì)的解釋:redux的源碼內(nèi)部是怎么處理中間件的。為了幫助大家更好的理解,先給大家扯點(diǎn)東西。redux的中間件都是遵循一定規(guī)范的。不管是官方的中間件還是我們以后需要自己寫(xiě)的中間件,其函數(shù)簽名都是一定的。也就是說(shuō),中間件的基本的格式都是一樣的,接收的參數(shù)也是redux注入進(jìn)去的。下面就是redux中間件的基本格式:
const reduxMiddleware = ({dispatch, getState}[簡(jiǎn)化的store]) => (next[上一個(gè)中間件的dispatch方法]) => (action[實(shí)際派發(fā)的action對(duì)象]) => {}
到這里,我們就可以去深究redux中間件的源碼了:
export default function applyMiddleware(...middlewares) { // middlewares就是我們傳遞給applyMiddlewarez函數(shù)的一系列中間件函數(shù) return (createStore) => (...args) => { // createStore就是redux用于創(chuàng)建store的方法,args === [reducers, preloadedState]。下面這句話就是在中間件的內(nèi)部,使用我們傳遞的參數(shù)創(chuàng)建一個(gè)store對(duì)象 // 注:這一塊沒(méi)有傳遞enhancer,所以返回的就是我們經(jīng)常使用的store對(duì)象 const store = createStore(...args) // 獲取store對(duì)象的dispatch方法 let dispatch = store.dispatch // 保存的是中間件函數(shù)的第二層函數(shù) let chain = [] // 傳遞給中間件的第一層的函數(shù)的參數(shù), const middlewareAPI = { getState: store.getState, // 重寫(xiě)了dispatch方法,其實(shí)就是store.dispatch(...args) dispatch: (...args) => dispatch(...args) } /** * 著重給大家詳細(xì)的解釋一下這一塊 * 假設(shè)我們給applyMiddleware函數(shù)傳遞的中間件是 * applyMiddleware( * f1 => g1 => h1(...arg) => {}, * f2 => g2 => h2(...arg) => {} * ) * 運(yùn)行下面的這行代碼之后,chain中保存的內(nèi)容是 * chain = [g1 => h1(...arg) => {}, g2 => h2(...arg) => {}] */ chain = middlewares.map(middleware => middleware(middlewareAPI)) /** * 當(dāng)我們把chain傳入到 compose中后,根據(jù)我們對(duì)compose的分析, * compose(...chain)(store.dispatch)的結(jié)果就是: * g1(h2(...arg)) => h1(...arg) * * 也就是說(shuō),按照上面的這個(gè)形式,下面的dispatch和h1函數(shù)是一樣的,所以,h1的參數(shù),就是我們需要派發(fā)的action,當(dāng)我們調(diào)用dispatch的時(shí)候,其實(shí)就相當(dāng)于調(diào)用h1(action),而在h1的內(nèi)部,這個(gè)action是由g1的參數(shù) * 也就是h2進(jìn)行派發(fā)的,所以這個(gè)時(shí)候action就傳遞到了h2的內(nèi)部,而h2的參數(shù)是由g2的參數(shù),也就是實(shí)際傳入的store.dispatch進(jìn)行派發(fā)的,就這樣層層傳入,層層輸出,就形成了我們強(qiáng)大的中間件機(jī)制。 */ dispatch = compose(...chain)(store.dispatch) // 返回的也是一個(gè)store對(duì)象 return { ...store, // 這個(gè)dispatch其實(shí)就是,各個(gè)中間件的最底層(第三層)的哪個(gè)函數(shù)組成的圓環(huán)函數(shù)構(gòu)成的 dispatch } } }
這就是對(duì)applyMiddleware源碼的一個(gè)整體解讀,水平有限,歡迎拍磚。后續(xù)的源碼解讀和測(cè)試?yán)涌梢躁P(guān)注:redux源碼解讀倉(cāng)庫(kù)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/92378.html
摘要:源碼解析是最核心的模塊。比如,當(dāng)我們需要使用中間件的時(shí)候,就會(huì)像第三個(gè)參數(shù)傳遞一個(gè)返回值是一個(gè)。后續(xù)的源碼解讀和測(cè)試?yán)涌梢躁P(guān)注源碼解讀倉(cāng)庫(kù) createStore源碼解析 createStore是redux最核心的模塊。這個(gè)模塊就是用于創(chuàng)建一個(gè)store對(duì)象,同時(shí),對(duì)外暴露出dispatch,getState,subscribe和replaceReducer方法。(源碼中關(guān)于obse...
摘要:否則的話,認(rèn)為只是一個(gè)普通的,將通過(guò)也就是進(jìn)一步分發(fā)。在本組件內(nèi)的應(yīng)用傳遞給子組件源碼解析期待一個(gè)作為傳入,里面是如果只是傳入一個(gè),則通過(guò)返回被綁定到的函數(shù)遍歷并通過(guò)分發(fā)綁定至將其聲明為的屬性之一接收的作為傳入。 原文鏈接:https://github.com/ecmadao/Co...轉(zhuǎn)載請(qǐng)注明出處 本文不涉及redux的使用方法,因此可能更適合使用過(guò)redux的玩家翻閱? 預(yù)熱...
摘要:主模塊的入口模塊就是。主要就做兩件事引入個(gè)功能模塊,并掛載至同一個(gè)對(duì)象上,對(duì)外暴露。在非環(huán)境下壓縮代碼,給予警告。后續(xù)的源碼解讀和測(cè)試?yán)涌梢躁P(guān)注源碼解讀倉(cāng)庫(kù) 主模塊 redux的入口模塊就是src/index.js。這個(gè)文件的代碼十分簡(jiǎn)單。主要就做兩件事: 引入個(gè)功能模塊,并掛載至同一個(gè)對(duì)象上,對(duì)外暴露。 在非production環(huán)境下壓縮代碼,給予警告。 下面是模塊的源碼(只包...
摘要:這里還有一個(gè)疑問(wèn)點(diǎn)就是的嵌套,最開(kāi)始也我不明白,看了源碼才知道,這里返回的也是接受也就是一個(gè)所以可以正常嵌套。以作為參數(shù),調(diào)用上一步返回的函數(shù)以為參數(shù)進(jìn)行調(diào)用。 1、本文不涉及redux的使用方法,因此可能更適合使用過(guò) redux 的同學(xué)閱讀2、當(dāng)前redux版本為4.0.13、更多系列文章請(qǐng)看 Redux作為大型React應(yīng)用狀態(tài)管理最常用的工具。雖然在平時(shí)的工作中很多次的用到了它...
摘要:函數(shù)組合,科里化的串聯(lián)結(jié)合示例源碼,實(shí)現(xiàn)也很優(yōu)雅,對(duì)于返回的,將等參數(shù)傳遞進(jìn)去,然后執(zhí)行,等待回調(diào)異步完成再。對(duì)于正常對(duì)象則進(jìn)行下一步。前言 作為前端狀態(tài)管理器,這個(gè)比較跨時(shí)代的工具庫(kù)redux有很多實(shí)現(xiàn)和思想值得我們思考。在深入源碼之前,我們可以相關(guān)注下一些常見(jiàn)問(wèn)題,這樣帶著問(wèn)題去看實(shí)現(xiàn),也能更加清晰的了解。 常見(jiàn)問(wèn)題 大概看了下主要有這么幾個(gè): redux三大原則 這個(gè)可以直接參考...
閱讀 3179·2023-04-25 19:09
閱讀 3888·2021-10-22 09:54
閱讀 1764·2021-09-29 09:35
閱讀 2919·2021-09-08 09:45
閱讀 2264·2021-09-06 15:00
閱讀 2775·2019-08-29 15:32
閱讀 1041·2019-08-28 18:30
閱讀 376·2019-08-26 13:43