深入理解redux中介軟體

2021-09-18 02:18:56 字數 4060 閱讀 2072

摘自:please call me hr

redux middleware 是 redux 的乙個 advanced feature. 這個概念並不是很新奇,以為在 koa 裡面早已經實現過了. 對比與原生的redux middleware , koa 的 middleware 差不多相當於是爸爸級的 level 了. 這麼說,是有依據的. 我們這裡,來深入一下原始碼,具體看一下redux middleware 到底做了些啥.

我們首先來**一下基本的原始碼吧.

redux 的原始碼可以說是比較簡單的。 首先,入口檔案是 index.js 。我們來看一下,裡面具體的內容:

// 從不同的檔案裡面匯出相關方法

export

compose 的原始碼就是乙個函式 compose :

export default function compose(...funcs) 

if (funcs.length === 1)

// 獲取最後乙個函式

const last = funcs[funcs.length - 1];

// 獲取除最後乙個以外的函式[0,length-1)

const rest = funcs.slice(0, -1)

// 通過函式 curry 化

return (...args) => rest.reduceright((composed, f) => f(composed), last(...args))

}

第一眼看的時候, 肯定超級s b。。。 md... 這寫個啥... 看了一下官方給的注釋就是:

// 簡單 demo 就是

compose(f, g, h) is identical to doing (...args) => f(g(h(...args))).

合著就是個函式巢狀的寫法。。。

關鍵坑爹的在於他的reduceright方法, 寫的真心6. 由於,return 兩個函式時,只會返回第二個執行的結果:

function test(a,b)

console.log(test(a=>1,b=>2));

// 開玩笑的. 上面那種只是科普一下. 他真正的機制實際上是利用 reduceright 的第二個引數來執行的

array.reduceright(fn,start);

// 主要還是這裡的start, 相當於就是 last(...args)

// 將上面**翻譯一下就是

rest.reduceright(function(composed, f), last(...args));

//... 慢慢去體會吧...

所以, 一開始看的時候,在糾結 最後乙個 composed 都沒執行... 後來發現, 原來還有一層 last(...args).

不過實話說, 真心沒有 koa 裡面的 compose 函式寫得好, 你直接先寫乙個 noop 函式不行嗎!!!

// 俺 實際寫了乙個替換的compose. 感覺這個看的清楚一點

function compose(...funcs)

return middle;

}}// 測試

console.log(compose(a => a, b => b, (c,b) => c+b)('a', 'b'));

由於這個中介軟體有點複雜, 對傳入的函式有具體的要求. 我們先來看一下使用該方法的上下文:

直接看 offical website 找到乙個 demo:

let store = createstore(

)

function createstore(reducer, preloadedstate, enhancer) 

if (typeof enhancer !== 'undefined')

return enhancer(createstore)(reducer, preloadedstate)

}}

// 這裡就看一下logger 就ok

const logger = store => next => action =>

// 我們將 debug 資訊去掉之後,可以得到乙個精簡版的 middleware

const logger = store => next => action =>

看到這裡,有種 koa 的感覺. next(action) 顯示的將控制權交給下乙個函式進行執行. 相當於就是 onion model.

return (createstore) => (reducer, preloadedstate, enhancer) =>

chain = middlewares.map(middleware => middleware(middlewareapi))

dispatch = compose(...chain)(store.dispatch)

return

}}store.dispatch(action)

如果按照上面的呼叫方式寫的話,具體呼叫順序就是:

關於 redux-middleware 還有乙個比較流行的庫, 即, redux-thunk . 該庫灰常簡單, 就乙個函式.

直接看原始碼算了:

function createthunkmiddleware(extraargument) ) => next => action => 

return next(action);

};}const thunk = createthunkmiddleware();

thunk.withextraargument = createthunkmiddleware;

export default thunk;

他和原來的中介軟體的寫法有乙個非常不同的地方,在於. 他寫中介軟體的地方, 不在 createstore 裡面, 而在 dispatch 裡面.

// 初始化呼叫

const store = createstore(

rootreducer,

);// thunk 型別的中介軟體

function dosth(forperson) ;

}// 更簡便的寫法可以為:

let dosth = forperson=>dispatch=> async().then(

sauce => dispatch(makeasandwich(forperson, sauce)),

error => dispatch(apologize('the sandwich shop', forperson, error))

)

看原始碼,我們可以很容易發現, 在實際呼叫 dispatch 時, 不僅僅只有 dispatch 這乙個引數,還有 getstate,extraargument 這兩個引數。 so, what are they doing?

getstate 這個就不用說了, 就是用來獲取當前 redux 的 state.

那 extraargument 幹啥嘞?

看原始碼很容易發現, 就是在初始化 thunk 時, 傳入的引數. 其實, 也不會經常用到. 所以, 我們中介軟體實際可以寫為:

let dosth = forperson=>(dispatch,getstate,extargs)=> async().then(

sauce => dispatch(makeasandwich(forperson, sauce)),

error => dispatch(apologize('the sandwich shop', forperson, error))

)

redux深入理解之中介軟體 middleware

本文 請看本人github,關於redux運用,請看之前一篇文章 reduce 方法接收乙個函式作為累加器 accumulator 陣列中的每個值 從左到右 開始縮減,最終為乙個值。arr.reduce callback,initialvalue 關於reduce的用法,這裡不再做多述,可以去這裡檢...

redux深入理解之中介軟體 middleware

本文 請看本人github,關於redux運用,請看之前一篇文章 reduce 方法接收乙個函式作為累加器 accumulator 陣列中的每個值 從左到右 開始縮減,最終為乙個值。arr.reduce callback,initialvalue 關於reduce的用法,這裡不再做多述,可以去這裡檢...

理解redux中介軟體

1.reducers 函式如何建立和聚合 2.action建立函式如何如何包裹在dispatch函式中 3.如何給預設的dispatch方法增加中介軟體能力 js context 中介軟體由函式組合的形式建立,實現與主要執行任務正交的功能。tips 類似的有裝飾器模式 在 redux middlew...