Redux 中间件 compose 函数的实现原理
请实现 Redux 中的 compose 工具函数,并解释如何通过函数组合(Function Composition)将多个中间件链式组合成增强的 dispatch 函数。
回答
孤独的心
compose 函数实现:
// 从右向左组合函数
function compose(...funcs) {
if (funcs.length === 0) {
return (arg) => arg;
}
if (funcs.length === 1) {
return funcs[0];
}
return funcs.reduce((a, b) => (...args) => a(b(...args)));
}
// 使用示例:
const increment = (x) => x + 1;
const double = (x) => x * 2;
const square = (x) => x * x;
const composed = compose(square, double, increment);
console.log(composed(5)); // ((5 + 1) * 2)² = 144
在 Redux 中间件中的使用:
// 伪代码
const middlewares = [thunk, logger, saga];
// 每个中间件的形式:({ getState, dispatch }) => (next) => (action) => { ... }
// 传入 store API 生成 chain
const chain = middlewares.map(mw => mw({ getState, dispatch }));
// compose 从右到左执行:
// chain[n](...chain[2](chain[1](store.dispatch)))
// 执行顺序从左到右(因为 compose 从右向左组合)
const enhancedDispatch = compose(...chain)(store.dispatch);
执行顺序图示:
compose(A, B, C)(dispatch)
→ A(B(C(dispatch)))
发送 action 时:
A(next=B(C(dispatch))) 先执行
→ B(next=C(dispatch)) 执行
→ C(next=dispatch) 执行
→ 原始 dispatch
← C 后续
← B 后续
← A 后续
手写简化版:
function applyMiddleware(...middlewares) {
return createStore => (reducer, preloadedState) => {
const store = createStore(reducer, preloadedState);
let dispatch = store.dispatch;
const middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action),
};
const chain = middlewares.map(mw => mw(middlewareAPI));
dispatch = compose(...chain)(store.dispatch);
return { ...store, dispatch };
};
}