CodeWalk

Redux 中间件 compose 函数的实现原理

作者:孤独的心 · 2026-05-30 12:55

请实现 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 };
  };
}