什么是中间件
在redux中,我们可以在view层dispatch一个action,action到达store中的reducer,reducer根据action的type更新处理state,从而更新store中的数据。但是redux并不能处理异步的dispatch。这时候我们就需要使用redux提供的applyMiddleware对dispatch进行增强,使我们的dispatch可以异步。
这里重点讨论applyMiddleware这个中间层,是如何工作的。
中间件的使用
const store = createStore(myReducer, applyMiddleware(logger, thunk));
分析下源码,createStore是如何使用这个applyMiddleware的勒?看看下面这段源码yourProject\node_modules\_redux@4.0.5@redux\lib\redux.js
,applyMiddleware(logger, thunk)
执行的结果就是enhancer,作为一个增强器去包装处理reducer。
function createStore(reducer, preloadedState, enhancer) {
···
if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
enhancer = preloadedState;
preloadedState = undefined;
}
···
return enhancer(createStore)(reducer, preloadedState); // 关键代码
}
那咱们接下来看看applyMiddleware(logger, thunk)
执行的结果enhancer是个什么呢?
中间件applyMiddleware做了什么
源码地址也是在这里哦,yourProject\node_modules\_redux@4.0.5@redux\lib\redux.js
。
// 中间件
function applyMiddleware() {
// 将fn参数收集到middlewares,这是一个fn数组
for (var _len = arguments.length, middlewares = new Array(_len), _key = 0; _key < _len; _key++) {
middlewares[_key] = arguments[_key];
}
// 返回一个函数,enhancer,看看enhancer的调用,enhancer(createStore)(reducer, preloadedState);
return function (createStore) {
// 又返回一个函数,此时参数为(reducer, preloadedState)
return function () {
// 利用初始reducer,创建store,这个store和咱们没有用中间件的时候一样哦~
var store = createStore.apply(void 0, arguments);
var _dispatch = function dispatch() {
throw new Error('Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.');
};
// 对store进行了简单的包装,用于拦截增强函数中的dispatch
var middlewareAPI = {
getState: store.getState,
dispatch: function dispatch() {
return _dispatch.apply(void 0, arguments);
}
};
// 关键代码,遍历fn数组,将middlewareAPI(包装过的store)作为参数传递进去执行该函数
var chain = middlewares.map(function (middleware) {
return middleware(middlewareAPI);
});
// compose是一个基于reduce的方法,将fn数组进行套娃[fn1, fn2, fn3] => fn1(fn2(fn3(arguments)))
// fn1(fn2(fn3(arguments)))的实参是真实原始的dispatch,真正意义上的对原始dispatch做增强
_dispatch = compose.apply(void 0, chain)(store.dispatch);
// 返回store,此时store拥有superDispatch啦!
return _objectSpread2({}, store, {
dispatch: _dispatch
});
};
};
}
// 组装器
function compose() {
···
return funcs.reduce(function (a, b) {
return function () {
return a(b.apply(void 0, arguments));
};
});
}