原文发布在我的个人博客 解读只有99行的Redux(二) | 以太空间
在使用Redux的时候我们可能会遇到异步操作的问题,希望让 Reducer 在异步操作结束后自动执行,所以我们就用了中间件(middleware)。
先看一下中间件的一般形式:
const middleware = store => reducer => next => {
...//这一行可能会获取store的state并使用
let result = next(action);
...//这一行可能会获取store的state并使用
return result
}
在真正的Redux环境中,我们一般是这样使用中间件的:
const { createStore, applyMiddleware} = Redux
const store = createStore(reducer,
applyMiddleware(loggerMiddleware, confirmationMiddleware)
);
不过,因为我们现在解读的是slim-redux,所以我们这样使用
const { createStore, applyMiddleware} = Redux
const store = applyMiddleware(
loggerMiddleware,
confirmationMiddleware)(createStore)(reducer);
compose
解读export function compose(...funcs) {
return arg => funcs.reduceRight((composed, f) => f(composed), arg);
}
要想理解下面的applyMiddleware
,就得先搞懂这个compose
。
它的作用就是从右到左来组合多个函数,这是函数式编程中的方法,为了方便,被放到了 Redux 里。
它需要合成的多个函数。预计每个函数都接收一个参数。它的返回值将作为一个参数提供给它左边的函数,以此类推。例外是最右边的参数可以接受多个参数,因为它将为由此产生的函数提供签名。
compose(funcA, funcB, funcC)
形象为 compose(funcA(funcB(funcC())))
applyMiddleware
解读export function applyMiddleware(...middlewares) {
return (createStore) => (reducer, initialState) => {
var store = createStore(reducer, initialState);
var dispatch = store.dispatch;
var chain = [];
chain = middlewares.map(middleware => middleware({
getState: store.getState,
dispatch: (action) => dispatch(action)
}));
dispatch = compose(...chain)(store.dispatch);
return { ...store, dispatch };
};
}
applyMiddleware
是一个高阶函数,我们从最内层的函数开始:
首先调用createStore
得到了一个store
,然后保存这个store
的dispatch
到dispatch
,再声明一个chain
数组。
对最外层函数applyMiddleware
的剩余参数middlewares
进行遍历,对每一个middleware
,传入一个临时store{getState: store.getState, dispatch: (action) => dispatch(action)}
作为参数调用它。根据上面middleware的形式,其结果是以下的形式的函数
function (next) {
return function (action) {
return next(action);
};
}
遍历结束后,chain
数组里面每个元素都是类似上面这样的函数。
最后使用compose
函数将chain
数组里面的每个函数元素组合起来最后传入store.dispatch
整个调用过程类似下面的结构:
function (next1) {
return function (next2) {
return function (next3) {
return next4(store.dispatch);
}
}
}
经过层层封装,dispatch
已经不是原来的dispatch
。调用这个dispatch
的时候,我们想要的功能都会在中间完成,整个调用过程如下图所示:
最后解构store并返回,新的dispatch覆盖原来的dispatch
以下是解读只有99行的Redux系列的其他两篇文章
解读只有99行的Redux(一) 从创建一个store开始
解读只有99行的Redux(三) 辅助函数和组合Reducer