
这是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)
这正好是对上面三层嵌套的实现