redux中間件執行原理?

學習過react的同窗確定都用過redux。瞭解redux數據流機制的action->dispatch->store->reduce->頁面交互其實很好理解,但是當咱們要用到異步請求或者打印日誌之類的副操做的時候,咱們沒法避免的會用到中間件Middleware。中間件都是怎麼執行以及如何有序的串在一塊兒很使人迷惑,下面我將嘗試解釋這個過程:react

演變過程

假如你有個需求須要在分發dispatch先後打印不一樣狀態值,你確定會這麼想:redux

console.log('dispatching', action)
store.dispatch(action)
console.log('next state', store.getState())
複製代碼

封裝成函數:bash

function dispatchAndLog(store, action) {
  console.log('dispatching', action)
  store.dispatch(action)
  console.log('next state', store.getState())
}
//執行
dispatchAndLog(store,  action)
複製代碼

不妨改造store的dispatch更爲直接些:app

let next = store.dispatch
store.dispatch = function dispatchAndLog(action) {
  console.log('dispatching', action)
  let result = next(action)
  console.log('next state', store.getState())
  return result
}
複製代碼

Redux把這個封裝的入口寫成了一個函數,就叫applyMiddleware。由此咱們明白了applyMiddleware的功能:改造dispatch函數,產生真假dispatch,而中間件就是運行在假真(dispatchAndLog假和next真)之間的代碼。異步

這裏咱們要對applyMiddleware進行一個準確的定義,它只是一個用來加工dispatch的工廠,而要加工什麼樣的dispatch出來,則須要咱們傳入對應的中間件函數(好比上例中的dispatchAndLog),下面咱們構造一個精簡版的applyMiddleware:函數

function applyMiddleware(middleware){
  let next = store.dispatch;
  store.dispatch = middleware(store)(next);  // 這裏傳入store,是由於中間件中有可能會用到getState獲取數據,好比打印當前用戶等需求 
 }
}
applyMiddleware(dispatchAndLog)
複製代碼

中間串連

中間件的功能各不相同,它們都要融入到dispatch中,在派發action的時候,按照順序一個個的執行,這是一個費腦經的事情。在上例中middleware會返回新的dispatch,咱們須要作的也就是將產生的新的dispatch傳遞個下箇中間件便可。以下:學習

function applyMiddleware(middleware,middleware2){
  let next = store.dispatch;
  store.dispatch = middleware2(middleware(store)(next));  
  // 這裏傳入store,是由於中間件中有可能會用到getState獲取數據,好比打印當前用戶等需求 
 }
}
applyMiddleware(dispatchAndLog,dispatchmethed)
複製代碼

以此類推有大量的中間件的時候咱們能夠這麼幹:ui

function applyMiddleware(...middlewares){
    middlewares = middlewares.slice();
    middlewares.reverse();  //執行順序是後到前,因此得倒置
    let dispatch = store.dispatch
    //循環嵌套
    middlewares.foreach(function(middleware){
        dispatch = middleware(store)(dispatch);
    });
    return  Object.assign({}, store, { dispatch }); //合併dispatch到redux裏。
}
複製代碼

請注意這裏是一個循環嵌套的一個過程,因此中間的順序決定着中間件的執行順序。spa

總結兩點:日誌

  1. 中間件在執行完副操做會並會返回新的dispatch
  2. applyMiddleware本質是一個循環嵌套調用的過程。

參考:zhuanlan.zhihu.com/p/34651008

相關文章
相關標籤/搜索