国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Redux-Middleware-原理解析

ideaa / 490人閱讀

摘要:再學習的過程中這塊感覺很燒腦所以對它的原理進行整理有一些比較基礎的先不整理以日志中間件為例以下的這種寫法屬于柯里化的知識以上的代碼可以解釋成源碼假如說里有三個一個保存了狀態和方法的對象這個對應的就是的通過閉包的形式引用外部的執行了方法返回了

再學習redux的過程中,Middleware這塊感覺很燒腦,所以對它的原理進行整理

有一些比較基礎的先不整理,

以日志中間件為例

//以下的這種寫法屬于柯里化的知識
const logger = state => next => action =>{
    console.log("dispatch", action);
    next(action);
    console.log("nextState",store.getState);
}

以上的代碼可以解釋成

var logger = function logger(state) {
    return function (next) {
        return function (action) {
            console.log("dispatch", action);
            next(action);
            console.log("nextState", store.getState);
        };
    };
};
//applyMiddleware 源碼
export default function applyMiddleware(...middlewares) {
  //假如說 middlewares 里有三個mid1,mid2,mid3
  return (createStore) => (reducer, preloadedState, enhancer) => {
    const store = createStore(reducer, preloadedState, enhancer)
    let dispatch = store.dispatch
    let chain = []

    //一個保存了store狀態,和dispatch方法的對象 這個對應的就是logger 的store
    const middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)//通過閉包的形式引用外部的dispatch
    }
    //執行了middleware方法,返回了需要next參數的方法 的數組
    chain = middlewares.map(middleware => middleware(middlewareAPI))
    //假如chain 為[f1,f2,f3,f4,f5,f6,f7]
    //那么下面這句話的翻譯就是這樣   dispatch = f1(f2(f3(f4(f5(f6(f7(store.dispatch)))))))
    //就是將chain中的函數串聯到一起,這種組合從最里面開始執行,返回的結果作為上一個函數的參數,一直向外執行
    //就是相當于從chain函數的最右側到最左側執行
    //compose(...chain) 返回的是一個匿名函數  function compose(...funcs)  funcs就是chain
    //return funcs.reduce((a, b) => (...args) => a(b(...args))) 這里的args就是store.dispatch
    dispatch = compose(...chain)(store.dispatch)
    //dispatch = f1(f2(f3(f4(f5(f6(f7(store.dispatch)))))))
    //當調用dispatch的時候就依次執行
    return {
      ...store,
      dispatch// 這個是處理過的dispatch
    }
  }

}
 chain = middlewares.map(middleware => middleware(middlewareAPI))

這里可以看出來,在日志中間件中的第一層的store就是middlewareAPI
并且將第二層返回到chain的數組中
這就相當于當初的store => next => action =>{...}變成了next => action =>{...}

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

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)))
}

這一步相當于把chain數組中函數,通過處理得到一種類似于層層嵌套的結構f1(f2(f3(f4(args))))
所以dispatch = A(B(C(store.dispatch))

單個中間件較為簡單,所以拿三個中間件做例子
經上面所述

//因為拋開store,剩下的中間件的結構類似于下面這種
function A1(next){
  return function A2(action){
    next(action)
  }
}

function B1(next){
  return function B2(action){
    next(action)
  }
}

function C1(next){
  return function C2(action){
    next(action)
  }
}
//dispatch = A(B(C(store.dispatch))
//這種結構會先執行最內部的函數,也就是C(store.dispatch)這一塊
//當執行了C 返回的是一個函數
function C2(action){
    store.dispatch(action)
}

//返回值最為他的外層函數的參數next
next = function C2(action){
    store.dispatch(action)
}
//此時的結構類似于這種
dispatch = A(B(function C2(action) {
                    store.dispatch(action)
                }(action)
                )
            )
//接下來執行B,返回了
next = function C2(action){
    function C2(action){
        store.dispatch(action)
    }(action)
}
//此時的結構類似于這種
dispatch = A(function B2(action) {
                    function C2(action){
                        store.dispatch(action)
                    }(action)
                }(action)
            )
//接下來執行A,返回了
dispatch = function A2(action){
                function B2(action) {
                    function C2(action){
                        store.dispatch(action)
                    }(action)
                }(action)
            }(action)

最后返回新的store

總結

調用applyMiddleware 傳入n個中間件的數組

用一個middlewareAPI保存當前的store.getState,和dispatch所指向的函數

迭代中間件數組,并執行一遍,將middlewareAPI作為最外層的store,并且返回一個相當于next函數的數組

將數組整理成嵌套的函數體,并將store.dispatch傳入最內側的函數的next,并返回經過處理的dispatch (dispatch是一個經過處理的函數,是一個嵌套了多層的函數,其最里面調用的是store.dispatch)

返回一個新的store

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108025.html

相關文章

  • 瀏覽器工作原理整理

    摘要:每種可被解析的格式必須具有由詞匯及語法規則組成的特定的文法,稱為上下文無關文法。解析解析器,每個標識都有特定的正則進行解析。開發者可以將腳本標識為,以使其不阻塞文檔解析,并在文檔解析結束后執行。 瀏覽器組成 用戶界面-地址欄、按鈕之類的 瀏覽器引擎-用來查詢及操作渲染引擎的接口 渲染引擎-顯示請求的內容 網絡-進行網絡請求 ui后端-用來滬指選擇框、對話框的基本組件 js解析器 數據...

    hqman 評論0 收藏0
  • 瀏覽器工作原理整理

    摘要:每種可被解析的格式必須具有由詞匯及語法規則組成的特定的文法,稱為上下文無關文法。解析解析器,每個標識都有特定的正則進行解析。開發者可以將腳本標識為,以使其不阻塞文檔解析,并在文檔解析結束后執行。 瀏覽器組成 用戶界面-地址欄、按鈕之類的 瀏覽器引擎-用來查詢及操作渲染引擎的接口 渲染引擎-顯示請求的內容 網絡-進行網絡請求 ui后端-用來滬指選擇框、對話框的基本組件 js解析器 數據...

    Dionysus_go 評論0 收藏0
  • CDN工作原理

    摘要:通過以上四個步驟,瀏覽器完成從用戶處接收用戶要訪問的域名到從域名服務主機處獲取數據的整個過程。概念解析指別名記錄也被稱為規范名字可以理解為對域名設置別名。詳細可以參考一些名詞解釋 傳統的網絡訪問形式為: showImg(http://segmentfault.com/img/bVcqjG); 由上圖可見,用戶訪問未使用CDN緩存網站的過程為: 用戶向瀏覽器提供要訪問的域名; 瀏...

    zhonghanwen 評論0 收藏0
  • 【進階3-5期】深度解析 new 原理及模擬實現

    摘要:使用指定的參數調用構造函數,并將綁定到新創建的對象。由構造函數返回的對象就是表達式的結果。情況返回以外的基本類型實例中只能訪問到構造函數中的屬性,和情況完全相反,結果相當于沒有返回值。 定義 new 運算符創建一個用戶定義的對象類型的實例或具有構造函數的內置對象的實例。 ——(來自于MDN) 舉個栗子 function Car(color) { this.color = co...

    Baaaan 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<