這是redux應用了middleware之後的處理事件的流程圖,這跟node中的中介軟體的功能如出一轍,下面我們來看它的原始碼是如何實現的
function applyMiddleware() {
for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) {
middlewares[_key] = arguments[_key];
}
return function (createStore) {
return function (reducer, preloadedState, enhancer) {
var store = createStore(reducer, preloadedState, enhancer);
var _dispatch = store.dispatch;
var chain = [];
var middlewareAPI = {
getState: store.getState,
dispatch: function dispatch(action) {
return _dispatch(action);
}
};
chain = middlewares.map(function (middleware) {
return middleware(middlewareAPI);
});
_dispatch = _compose2['default'].apply(undefined, chain)(store.dispatch);
return _extends({}, store, {
dispatch: _dispatch
});
};
};
}
複製程式碼
只有二十多行的程式碼,卻非常精簡 middleware的設計有點特殊,是一層層包裹的匿名函式,
串聯性:是函數語言程式設計中的curry的實現,利用了curry函式具有延遲執行的特性,配合compose函式形成管道資料鏈
chain = middlewares.map(function (middleware) {
return middleware(middlewareAPI);
});
_dispatch = _compose2['default'].apply(undefined, chain)(store.dispatch);
複製程式碼
最後會形成_dispatch=mid1(mid2(mid3(...(store.dispathch)))),將最原始的dispatch進行了一個功能的增強
共享store:在中介軟體的執行過程中,store還是舊的,利用函式閉包的特性,保證後面拿到的store都是最新的
var middlewareAPI = {
getState: store.getState,
dispatch: function dispatch(action) {
return _dispatch(action);
}
};
chain = middlewares.map(function (middleware) {
return middleware(middlewareAPI);
});
複製程式碼
所以我們通常些構建store的時候可以這麼寫:
const store = applyMiddleware(mid1, mid2, mid3...)(createStore)(reducer, null)
複製程式碼
這正好是對上面三層巢狀的實現